You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 1.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. 'use strict';
  2. const pTimeout = require('p-timeout');
  3. module.exports = (emitter, event, opts) => {
  4. let cancel;
  5. const ret = new Promise((resolve, reject) => {
  6. if (typeof opts === 'function') {
  7. opts = {filter: opts};
  8. }
  9. opts = Object.assign({
  10. rejectionEvents: ['error'],
  11. multiArgs: false
  12. }, opts);
  13. let addListener = emitter.on || emitter.addListener || emitter.addEventListener;
  14. let removeListener = emitter.off || emitter.removeListener || emitter.removeEventListener;
  15. if (!addListener || !removeListener) {
  16. throw new TypeError('Emitter is not compatible');
  17. }
  18. addListener = addListener.bind(emitter);
  19. removeListener = removeListener.bind(emitter);
  20. const resolveHandler = function (value) {
  21. if (opts.multiArgs) {
  22. value = [].slice.apply(arguments);
  23. }
  24. if (opts.filter && !opts.filter(value)) {
  25. return;
  26. }
  27. cancel();
  28. resolve(value);
  29. };
  30. const rejectHandler = function (reason) {
  31. cancel();
  32. if (opts.multiArgs) {
  33. reject([].slice.apply(arguments));
  34. } else {
  35. reject(reason);
  36. }
  37. };
  38. cancel = () => {
  39. removeListener(event, resolveHandler);
  40. for (const rejectionEvent of opts.rejectionEvents) {
  41. removeListener(rejectionEvent, rejectHandler);
  42. }
  43. };
  44. addListener(event, resolveHandler);
  45. for (const rejectionEvent of opts.rejectionEvents) {
  46. addListener(rejectionEvent, rejectHandler);
  47. }
  48. });
  49. ret.cancel = cancel;
  50. if (typeof opts.timeout === 'number') {
  51. return pTimeout(ret, opts.timeout);
  52. }
  53. return ret;
  54. };