@@ -62,7 +62,82 @@ function Domain() {
62
62
}
63
63
```
64
64
65
+ 另外, domain 为了支持深层次的嵌套, 提供了 ` Domain#enter ` 和 ` Domain#exit ` 的 API。
66
+ 先来看 ` enter ` 的实现,
67
+ ``` js
68
+ Domain .prototype .enter = function () {
69
+ if (this ._disposed ) return ;
70
+
71
+ // note that this might be a no-op, but we still need
72
+ // to push it onto the stack so that we can pop it later.
73
+ exports .active = process .domain = this ;
74
+ stack .push (this );
75
+ _domain_flag[0 ] = stack .length ;
76
+ };
77
+ ```
78
+ 设置当前活跃的 ` domain ` , 并且为了便于回溯,将当前的 ` domain ` 加入到队列的后面,更新栈的深度。
79
+
80
+ 再看 ` exit ` 实现,
81
+ ``` js
82
+ Domain .prototype .exit = function () {
83
+ // skip disposed domains, as usual, but also don't do anything if this
84
+ // domain is not on the stack.
85
+ var index = stack .lastIndexOf (this );
86
+ if (this ._disposed || index === - 1 ) return ;
87
+
88
+ // exit all domains until this one.
89
+ stack .splice (index);
90
+ _domain_flag[0 ] = stack .length ;
91
+
92
+ exports .active = stack[stack .length - 1 ];
93
+ process .domain = exports .active ;
94
+ };
95
+ ```
96
+ 相反的, 退出当前的 ` domain ` , 更新长度,设置当前活跃的 ` domain ` 。
97
+
98
+ 读者可能好奇,我并没有显式地调用 ` enter ` , ` exit ` , 而只是简单的创建了一个 domain, 怎么会达到这种效果?
99
+
100
+ 读者可以看看 ` AsyncWrap::MakeCallback() ` , 每次C++ --> JS, 都会检查 domain, 如果使用,则会显式地调用他们。
101
+ 其他地方读者可以自行寻找。
102
+
103
+ 为了解决不在当前作用域的异常处理, Domain 也提供 ` Domain#add ` 和 ` Domain#remove ` 来增加 ` emitter ` 或者
104
+ ` Timer ` 。
105
+
106
+
107
+ 回到事件的根本, 什么时候触发domain的error事件?
108
+ ``` js
109
+ process ._fatalException = function (er ) {
110
+ var caught;
111
+
112
+ if (process .domain && process .domain ._errorHandler )
113
+ caught = process .domain ._errorHandler (er) || caught;
114
+
115
+ if (! caught)
116
+ caught = process .emit (' uncaughtException' , er);
117
+
118
+ // If someone handled it, then great. otherwise, die in C++ land
119
+ // since that means that we'll exit the process, emit the 'exit' event
120
+ if (! caught) {
121
+ try {
122
+ if (! process ._exiting ) {
123
+ process ._exiting = true ;
124
+ process .emit (' exit' , 1 );
125
+ }
126
+ } catch (er) {
127
+ // nothing to be done about it at this point.
128
+ }
129
+
130
+ // if we handled an error, then make sure any ticks get processed
131
+ } else {
132
+ NativeModule .require (' timers' ).setImmediate (process ._tickCallback );
133
+ }
134
+
135
+ return caught;
136
+ };
137
+ ```
65
138
139
+ 如果当前 process 使用了 domain, 也是就 ` process.domain ` 不为空,就调用 ` _errorHandler ` 来处理,
140
+ 当前也存在没有处理的情况,职责链来到 process, process 则触发 ` uncaughtException ` 事件。
66
141
67
142
68
143
### 总结
0 commit comments