Skip to content Skip to sidebar Skip to footer

Using Promises To Await Triggered Events

In the following code, thing is an external object that I don't control; I can't change how the event system of thing works. When fn is called, we return a promise whose executor l

Solution 1:

Don't do any awaiting inside the Promise constructor - you only should do the promisification of the asynchronous callback in there:

asyncfunctionfn() {
  awaita();
  awaitb();
  awaitc(); // this causes myEventreturnnewPromise(function(resolve, reject) {
    thing.once('myEvent', function(e) {
      resolve(e.data); // done
    });
  });
}

The thing that starts the process which eventually causes the event to be emitted is usually called inside the Promise executor callback as well (to catch synchronous exceptions), but usually it doesn't return a promise like your c function does.

Maybe this expresses the intent better:

asyncfunctionfn() {
  awaita();
  awaitb();
  const {data} = awaitnewPromise(resolve => {
    thing.once('myEvent', resolve);
    thing.c(); // this causes myEvent
  });
  return data;
}

Of course this assumes that you only need to start listening to the event when you've called the other ones. If you expect the event to fire before that, you essentially have a race with parallel execution - I'd recommend to use Promise.all in that case:

asyncfunctionfn() {
  awaita();
  awaitb();
  const [{data}, cResult] = awaitPromise.all([
    newPromise(resolve => thing.once('myEvent', resolve)),
    c()
  ]);
  return data;
}

If you have node v11.13.0 or higher you can use the events.once method so that you don't have to build the promise yourself - and it also handles error events correctly:

import { once } from'events';

async function fn () {
  await a()
  await b()
  await c()
  await once(thing, 'myEvent')
}

Post a Comment for "Using Promises To Await Triggered Events"