-
事件循环(event loop)
Paste_Image.png
js是单线程语言,这是由于设计者最初设计的时候,考虑到其只运行在浏览器端,不应该太复杂。
事件循环有两个重要部分:1.事件 2.事件的订阅者,也就是事件处理器。
一个Nodejs程序运行后,事件循环就会一直存在,抛出事件,直到程序结束运行。事件循环需借助操作系统进行实现,如select、epoll、kqueue、IOCP;Nodejs是对系统进行了进一步的封装(libuv)。
什么是 Event Loop?
[译]事件循环,Node.js背后的核心概念 -
setImmediate VS process.nextTick VS setTimeout(fn, 0)
- process.nextTick: 回调函数会被放入数组中,而且在下一次事件循环前一起执行;
- setImmediate: 回调函数放入链表中,下次循环结束后从链表中取出一个执行。
- setTimeout(fn, 0): 通过源码可知,它是按照setTimeout(fn, 1)执行的,因此如果一个时间循环的时间小于1ms,那么setImmediate在前,否则setTimeout(fn, 0)在前。 但是考虑到setTimeout(fn, 0)的性能问题,Node作者推荐采用setImmediate。
三者中process.nextTick的优先级最高,其次是setTimeout,但是这并不一定代表执行顺序。由于setTimeout采用红黑树实现,setImmediate采用链表实现;对比效率而言,Node中推荐采用setImmediate。
setImmediate vs nextTick vs setTimeout(fn, 0)
-
全局对象
Node的全局对象是global,浏览器中的全局变量是window,可以根据这个区分js是运行在浏览器中还是Node中。
在浏览器中,var定义的变量会挂载到window下,因此:var x=1; window.x==1 //true
;
在Node中,var定义的变量并不会挂载到global下,因此:var x=1; global.x==1 //false
。
Node还提供了process
、console
、setTimeout
等全局的对象或者方法。 -
exports
和module.exports
的区别
Nodje的输出是module.exports
。module.exports
默认是一个空对象{}
,exports
是指向其的引用。举个例子:
var aa = {};
var bb = aa; // bb就是aa的引用
bb.cc = 1;
aa.cc == 1 // true
aa = {dd:1}
bb.dd == 1 // false undefined
类似上述的例子去理解两者的区别:
```
// b.js 输出一个函数,改变了module.exports的默认值{},此时exports和module.exports不再指向同一个对象
module.exports = function (name, age) {
// exports = module.exports = function (name, age) { // 此时两者还是指向同一个对象
this.name = name;
this.age = age;
}
exports.sex = "male";
var Person = require("./b");
var person = new Person("Tony", 33);
console.log(person); // {name:"Tony", age:33}
console.log(Person.sex); // undefined
```
- 模块机制
模块优先从缓存中加载,模块分析按照.js
、.json
、.node
扩展名进行。
三种类型的模块: - 核心模块,如
http
,fs
。 -
.
、..
、/
等相对或绝对路径的文件模块。 - 非路径形式的文件模块,如从npm下载到本地的模块。
第3种模块,系统会迭代遍历当前目录或者父目录的node-modules
文件夹进行查找。如果找到的不是一个文件,而是一个文件夹,那么系统会解析文件夹的package.json
文件进行分析。
- uncaughtException
异常处理可以通过try...catch进行捕获;但是如果try中的异常是异步的,并不会被catch到:
try{
process.nextTick(function my_app(){
throw new Error('Catch me');
})
}catch(e){
// never called
}
异常没有被捕获到,就会通过事件冒泡最终触发uncaughtException事件。有uncaughtException时,服务会触发exist事件,造成进程退出。如果想监听uncaughtException处理服务的全局异常,可能会造成服务超时;进一步造成内存泄露和服务的不稳定。
比较好的处理方式是:借助cluster模式,针对异常返回一个错误码,然后重启该wordker实例。
NodeJS 异常处理 uncaughtException 篇
Node.js 异步异常的处理与domain模块解析
网友评论