73 lines
1.5 KiB
JavaScript
73 lines
1.5 KiB
JavaScript
|
'use strict';
|
||
|
const pTimeout = require('p-timeout');
|
||
|
|
||
|
module.exports = (emitter, event, opts) => {
|
||
|
let cancel;
|
||
|
|
||
|
const ret = new Promise((resolve, reject) => {
|
||
|
if (typeof opts === 'function') {
|
||
|
opts = {filter: opts};
|
||
|
}
|
||
|
|
||
|
opts = Object.assign({
|
||
|
rejectionEvents: ['error'],
|
||
|
multiArgs: false
|
||
|
}, opts);
|
||
|
|
||
|
let addListener = emitter.on || emitter.addListener || emitter.addEventListener;
|
||
|
let removeListener = emitter.off || emitter.removeListener || emitter.removeEventListener;
|
||
|
|
||
|
if (!addListener || !removeListener) {
|
||
|
throw new TypeError('Emitter is not compatible');
|
||
|
}
|
||
|
|
||
|
addListener = addListener.bind(emitter);
|
||
|
removeListener = removeListener.bind(emitter);
|
||
|
|
||
|
const resolveHandler = function (value) {
|
||
|
if (opts.multiArgs) {
|
||
|
value = [].slice.apply(arguments);
|
||
|
}
|
||
|
|
||
|
if (opts.filter && !opts.filter(value)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cancel();
|
||
|
resolve(value);
|
||
|
};
|
||
|
|
||
|
const rejectHandler = function (reason) {
|
||
|
cancel();
|
||
|
|
||
|
if (opts.multiArgs) {
|
||
|
reject([].slice.apply(arguments));
|
||
|
} else {
|
||
|
reject(reason);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
cancel = () => {
|
||
|
removeListener(event, resolveHandler);
|
||
|
|
||
|
for (const rejectionEvent of opts.rejectionEvents) {
|
||
|
removeListener(rejectionEvent, rejectHandler);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
addListener(event, resolveHandler);
|
||
|
|
||
|
for (const rejectionEvent of opts.rejectionEvents) {
|
||
|
addListener(rejectionEvent, rejectHandler);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
ret.cancel = cancel;
|
||
|
|
||
|
if (typeof opts.timeout === 'number') {
|
||
|
return pTimeout(ret, opts.timeout);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
};
|