|
前言:本节主要是Nodejs的初步应用
Model1:Nodejs:单进程
Nodejs是单进程的,同一时期是只有一个进程执行Nodejs代码,单进程模式约束了我们在写JavaScript代码必须要使用非阻塞、异步的方式。
Model2:阻塞与非阻塞的区别
Demo案例:
var http = require('http')
http.createServer(function(req,res){
var url = req.url
console.log("Current url : " + url)
res.writeHead("200",{"content-type":"text/html"})
res.write("Hello World")
res.end()
}).listen(8888,function(){
console.log("The server is start to : 8888")
})
console.log("欢迎来到Nodejs世界。")
输出结果:
E:\NodejsWorkSpace>node Demo1.js
欢迎来到Nodejs世界
The server is start to : 8888
解析:
输出顺序:
因为Nodejs是采用异步回调的方式,listen执行时机是在请求结果返回后在执行。
插曲:
为了避免重复的重启cmd窗口,需要开启监听进程:
cmd->npm install supervisor -g
cmd->supervisor -h 如果显示帮助文档即为安装成功
使用监听:
cmd->supervisor Demo1.js
输出日志信息:
DEBUG: Starting child process with 'node Demo1.js'
为node Demo1.js开启一个子进程(用于执行)
DEBUG: Watching directory 'E:\NodejsWorkSpace' for changes.
监视目录文件是否改变(如果文件内容改变,则卸载子进程,重新开启)
当内容改变时,cmd窗口会自动输出更改后的信息
Demo改动:
var http = require('http'), //插入标点
sleep = function(milliSecond){ //插入函数
var start = new Date().getTime() + milliSecond
while(new Date().getTime() < start){}
}
http.createServer(function(req,res){
var url = req.url
sleep(5000) 插入
...
现象:
在两个浏览器同时请求http://localhost:8888/时,后刷新的会延迟加载5秒。
解析:
这就模拟了同步的现象,sleep相当于同步的函数。而Nodejs推荐使用异步。
Model3:多线程模型和事件驱动模型区别:
1、传统的IIS和Apache服务器是多线程模型,当服务器开启后,等待客户端的请求,当收到链接请求后会开启一个线程从头到尾服务该请求。如果处理该请求当中涉及访问外部数据源(数据库、文件)等耗时操作,会导致请求会被阻塞,被称为阻塞式IO。当链接越来越多的时候,将会导致服务延时,甚至崩溃。因为每个请求就要开启一个线程,如果想要提高服务器性能,就要同时处理多个线程。假设每个线程2M,10个就是20M。以及本身线程延时,使多个线程重叠处理。而无休止的增长,会使大量的线程重叠处理。
2、时间驱动模型:当WebServer接收到请求,将请求分发给相应的线程做处理。主线程会继续接收和服务下一个请求。当之前的请求完成后,它会被放入到一个待处理的列表(处理完成,待主线程调用的队列),当请求到达队列头的时候,主线程会调用当初注册的回调函数,并且把结果返回给客户端。
Model4:异步回调代码维护问题:
Model5:Promise/A+规范的Deferred库:
在jQuery1.7版本中即增加了延迟对象(Deffered object)。这个就是Promise/A+规范的Deferred库。
例子:
$.get("test.php")
.done(function(){ alert("$.get succeeded"); })
.fail(function(){ alert("$.get failed!"); });
解析:
此方法代替回调函数,减少了回调函数所带来的多层嵌套的问题。
对于以上代码的解析:
var http = require('http')
//requires是Nodejs进入库的函数,类似于java里的import引入包
//参数'http'是官方提供的http编程工具包
//这几行代码分别实现了Web服务器和Web应用,解析http请求属于http的范围,根据请求的信息去输出///则属于Web应用的范围
http.createServer(function(req,res){
//http.createServer接收了一个回调函数,函数中的req是HttpServer的Request的实例,req是HttpSer//ver的Response的实例。
var url = req.url
//根据实例获得客户端请求的url
console.log("Current url : " + url)
//打印请求的url
res.writeHead("200",{"content-type":"text/html"})
//输出200的状态码,200:成功,301或者302:跳转,500:服务器错误。大括号包含了很多对象。
res.write("Hello World")
res.end()
//最后调用,并且只能调用一次。调用end后,上面的输出内容将发送到客户端。
//并且执行权将会给Nodejs主进程
//end后的任何操作都不会执行
req对象和res对象都是Nodejs里面EventEmitter事件对象的实例,它都继承了事件对象,继承后我们就可通过on监听事件:
代码:
var url = req.url
dataPosts = ""
req.on('data',function(dataPostChunk){
dataPosts += dataPostChunk
})
//data在解析Http内容区的时候,读内容体的时候执行
req.on('end',function(){
console.log("PostData : " + dataPosts)
})
//end是在解析完成之后执行
console.log("Current url : " + url)
...
访问http://localhost:8888/,控制台输出postData为空,这是因为没有接收到输出信息新建一张表单,action="http://localhost:8888",提交表单后,会在控制带看到信息 |
|
|