@@ -129,6 +129,50 @@ EventEmitter.init = function init(opts) {
129
129
}
130
130
} ;
131
131
132
+ var ProcessNextTick = typeof queueMicrotask === 'function'
133
+ ? queueMicrotask
134
+ : typeof setImmediate === 'function'
135
+ ? setImmediate
136
+ : setTimeout ;
137
+
138
+ function addCatch ( that , promise , type , args ) {
139
+ if ( ! that [ kCapture ] ) {
140
+ return ;
141
+ }
142
+
143
+ // Handle Promises/A+ spec, then could be a getter
144
+ // that throws on second use.
145
+ try {
146
+ var then = promise . then ;
147
+ if ( typeof then === 'function' ) {
148
+ then . call ( promise , undefined , function ( err ) {
149
+ ProcessNextTick ( function ( ) {
150
+ emitUnhandledRejectionOrErr ( that , err , type , args ) ;
151
+ } ) ;
152
+ } ) ;
153
+ }
154
+ } catch ( err ) {
155
+ that . emit ( 'error' , err ) ;
156
+ }
157
+ }
158
+
159
+ function emitUnhandledRejectionOrErr ( ee , err , type , args ) {
160
+ if ( typeof ee [ kRejection ] === 'function' ) {
161
+ ee [ kRejection ] . apply ( ee , [ err , type ] . concat ( args ) ) ;
162
+ } else {
163
+ // We have to disable the capture rejections mechanism, otherwise
164
+ // we might end up in an infinite loop.
165
+ var prev = ee [ kCapture ] ;
166
+
167
+ try {
168
+ ee [ kCapture ] = false ;
169
+ ee . emit ( 'error' , err ) ;
170
+ } finally {
171
+ ee [ kCapture ] = prev ;
172
+ }
173
+ }
174
+ }
175
+
132
176
// Obviously not all Emitters should be limited to 10. This function allows
133
177
// that to be increased. Set to zero for unlimited.
134
178
EventEmitter . prototype . setMaxListeners = function setMaxListeners ( n ) {
@@ -182,12 +226,29 @@ EventEmitter.prototype.emit = function emit(type) {
182
226
return false ;
183
227
184
228
if ( typeof handler === 'function' ) {
185
- ReflectApply ( handler , this , args ) ;
229
+ var result = ReflectApply ( handler , this , args ) ;
230
+
231
+ // We check if result is undefined first because that
232
+ // is the most common case so we do not pay any perf
233
+ // penalty
234
+ if ( result !== undefined && result !== null ) {
235
+ addCatch ( this , result , type , args ) ;
236
+ }
186
237
} else {
187
238
var len = handler . length ;
188
239
var listeners = arrayClone ( handler , len ) ;
189
- for ( var i = 0 ; i < len ; ++ i )
190
- ReflectApply ( listeners [ i ] , this , args ) ;
240
+ for ( var i = 0 ; i < len ; ++ i ) {
241
+ var result = ReflectApply ( listeners [ i ] , this , args ) ;
242
+
243
+ // We check if result is undefined first because that
244
+ // is the most common case so we do not pay any perf
245
+ // penalty.
246
+ // This code is duplicated because extracting it away
247
+ // would make it non-inlineable.
248
+ if ( result !== undefined && result !== null ) {
249
+ addCatch ( this , result , type , args ) ;
250
+ }
251
+ }
191
252
}
192
253
193
254
return true ;
0 commit comments