1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/**
* An `asyncEmit()` function that accepts an EventEmitter, an Array of args, and
* a callback function. If the emitter listener function has an arity
* > args.length then there is an assumed callback function on the emitter, which
* means that it is doing some async work. We have to wait for the callbacks for
* any async listener functions.
*
* It works like this:
*
* var emitter = new EventEmitter
*
* // this is an async listener
* emitter.on('something', function (val, done) {
* // val may be any number of input arguments
* setTimeout(function () {
* done()
* }, 1000)
* })
*
* // this is a sync listener, no callback function
* emitter.on('something', function (val) {
*
* })
*
* asyncEmit(emitter, 'something', [ 5 ], function (err) {
* if (err) throw err
* console.log('DONE!')
* })
*/
module.exports = asyncEmit
function asyncEmit (emitter, eventName, args, callback) {
if (typeof args == 'function') {
callback = args
args = []
}
var async = emitter.listeners(eventName).filter(function (func) {
return func.length > args.length
}).length
var argv = [ eventName ].concat(args)
// callback function
argv.push(function (err) {
if (err && !callback.called) {
callback.called = true
callback(err)
}
--async || callback()
})
// no async listeners
if (async === 0) {
process.nextTick(callback)
}
return emitter.emit.apply(emitter, argv)
}
|