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;
 | |
| };
 |