1.process.nextTick(callback)
它的功能是为事件循环设置一项任务,nodeJs会在下一个事件循环时调用callback.
Node.js是单线程的,除了系统IO之外,在它的事件轮询过程中,同一时间只会处理一个事件。你可以把事件轮询想象成一个大的队列,在每个时间点上,系统只会处理一个事件。即使你的电脑有多个CPU核心,你也无法同时并行的处理多个事件。但也就是这种特性使得node.js适合处理I/O型的应用,不适合那种CPU运算型的应用。在每个I/O型的应用中,你只需要给每一个输入输出定义一个回调函数即可,他们会自动加入到事件轮询的处理队列里。当I/O操作完成后,这个回调函数会被触发。然后系统会继续处理其他的请求。
在这种处理模式下,process.nextTick()的意思就是定义出一个动作,并且让这个动作在下一个事件轮询的时间点上执行。我们来看一个例子。例子中有一个foo(),你想在下一个时间点上调用他,可以这么做:
function foo() {
console.error('foo');
}
process.nextTick(foo);
console.error('bar');
输出结果为:
bar
foo
你也可以使用setTimeout()函数来达到貌似同样的执行效果:
setTimeout(foo, 0);
console.log(‘bar’);
但在内部的处理机制上,process.nextTick()和setTimeout(fn, 0)是不同的,process.nextTick()不是一个单纯的延时,他有更多的 特性。
更精确的说,process.nextTick()定义的调用会创建一个新的子堆栈。在当前的栈里,你可以执行任意多的操作。但一旦调用netxTick,函数就必须返回到父堆栈。然后事件轮询机制又重新等待处理新的事件,如果发现nextTick的调用,就会创建一个新的栈。
下面我们来看看,什么情况下使用process.nextTick():
在多个事件里交叉执行CPU运算密集型的任务:
在下面的例子里有一个compute(),我们希望这个函数尽可能持续的执行,来进行一些运算密集的任务。
但与此同时,我们还希望系统不要被这个函数堵塞住,还需要能响应处理别的事件。这个应用模式就像一个单线程的web服务server。在这里我们就可以使用process.nextTick()来交叉执行compute()和正常的事件响应。
var http = require('http');
function compute() {
// performs complicated calculations continuously
// ...
process.nextTick(compute);
}
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World');
}).listen(5000, '127.0.0.1');
compute();
在这种模式下,我们不需要递归的调用compute(),我们只需要在事件循环中使用process.nextTick()定义compute()在下一个时间点执行即可。在这个过程中,如果有新的http请求进来,事件循环机制会先处理新的请求,然后再调用compute()。反之,如果你把compute()放在一个递归调用里,那系统就会一直阻塞在compute()里,无法处理新的http请求了。你可以自己试试。
当然,我们无法通过process.nextTick()来获得多CPU下并行执行的真正好处,这只是模拟同一个应用在CPU上分段执行而已。
2.util.inherits:
子类仅仅继承父类在原型链上定义的函数或属性,不会继承父类构造函数创建的属性及函数
3.util.innpect :
util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换
为字符串的方法,通常用于调试和错误输出。
showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。
depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多
少。如果不指定depth,默认会递归2层,指定为 null 表示将不限递归层数完整遍历对象。
如果color 值为 true,输出格式将会以 ANSI 颜色编码,通常用于在终端显示更漂亮
的效果。
特别要指出的是, util.inspect 并不会简单地直接把对象转换为字符串,即使该对
象定义了 toString 方法也不会调用。
var util = require('util');
function Person() {
this.name = 'fangchao';
this.age=23;
this.toString = function( ) {
return this.name;
};
}
var obj = new Person();
console.log(util.inspect(obj));
console.log("=======分割线==========");
console.log(util.inspect(obj, true));
console.log("=======分割线==========");
console.log(util.inspect(obj, true,2,true));
结果如下图:
4.事件驱动:
var event=require('events');
var emitter=new event.EventEmitter();
emitter.on("someevent",function(arg1,arg2){
console.log(arg1+" "+arg2);
});
emitter.emit("someevent","fangchao","zhaohonglei");
5.http.Server事件:
它继承自EventEmitter,提供了下面几个接口:
request:当客户端请求到来时,提供两个参数,req,res他们分别是http.ServerRequest和http.ServerResponse的实例,表示请求和响应信息。
connection:当Tcp连接建立的时候,该事件被触发,提供一个参数,为net.Socket的实例。
close:服务器关闭时
最常用的就是request了,因此http提供了一个捷径:http.createServer(requestListener),功能是创建一个服务器并将requestListener作为request事件的监听函数。
事实上它显式的实现方法是:
//httpserver.js
var http = require('http');
var server = new http.Server();
server.on('request', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Node.js</h1>');
res.end('<p>Hello World</p>');
});
server.listen(3000);
console.log("HTTP server is listening at port 3000.");