1.node 的回调异步特性,无法通过try-catch来捕获所有的异常
2.domain 捕捉异步回调中出现的异常
3.domain 虽然捕捉到了异常,但是还是由于异常而导致的堆栈丢失会导致内存泄漏,出现这种情况的时候还是需要重新启动这个进程的
4.node 为事件循环维持了一个队列,nextTick入队,_tickCallback 出列
5.domain 的隐式绑定
domain 主要会影响timers模块(包括 setTimeout 、setInterval、setImmediate),事件循环process.nextTick,还有event
实现思路:通过注入domain 代码到timer、nextTick、event模块中,在创建的时候检查当前有没有激活的domain,有则记录下;如果是timer和nextTick,当在事件循环中执行回调的时候,把process.domain
设置为之前记录的domain并把错误交个它处理。如果是event,多一步判断,先会把异常交给event自己定义的error事件处理.
domain 的显示绑定:
add 作用是把domain 创建之前创建的(EventEmitter 实例)对象添加到这个domain里边,然后这个对象即可使用domain 捕捉异常了,remove则相反。
6.domain 的实现
domain自身其实是一个EventEmitter 对象,它通过事件的方式来传递捕获的错误.
什么时候触发domain 的error事件:
进程抛出异常,没有被任何的 try catch 捕获到,这时候将会触发这个porcess 的processFatal,此时如果在domain包裹之中,将会在domain上触发error事件,反之,将会在process 上触发 uncaughtExcetion 事件。
domain 如何在多个不同的事件循环中传递:
nextTick 入队的时候,记录下当前的domain,当这个被加入队列中的事件循环被 _tickCallback启动执行的时候,将新的事件循环的process.domain 置为之前记录的 domain。这样在被 domain 所包裹的的代码中,不管如何调用process.nextTick,domain将会一直被传递下去
官方示例:https://nodejs.org/api/domain.html#domain_explicit_binding
参考网址:
http://www.alloyteam.com/2013/12/node-js-series-exception-caught/
https://cnodejs.org/topic/516b64596d38277306407936
网友评论