Can I use async/await to wait for multiple events in JavaScript?

async-await, asynchronous, ecmascript-2017, javascript

Solution

Since `async/await` allows us to write async constructs in a synchronous-looking manner (lexical top-down), there isn't really a specific approach to execute 3 different lines of code (or more accurately, statements) simultaneously.

The ideal api for this is the `Promise.race`.

First you convert your api callback into returning a promise:

const apiPromiseBuilder = (api) => (eventName) => new Promise(resolve => api.on(eventName, () => {
  resolve(eventName);
}));

Then you race all the events you need:

const waitForEvent = (api) => {

  const apiPromise = apiPromiseBuilder(api);

  const promiseRace = Promise.race([
    apiPromise('eventOne'),
    apiPromise('eventTwo'),
    apiPromise('eventThree')
  ]);

  api.load();

  return promiseRace;
};

Or using `async/await`:

async function waitForEvent(api) {

  const apiPromise = apiPromiseBuilder(api);

  const promiseRace = Promise.race([
    apiPromise('eventOne'),
    apiPromise('eventTwo'),
    apiPromise('eventThree')
  ]);

  api.load();

  const firstResult = await promiseRace;

  return firstResult;
};

Problem

Consider the following case: ``` const waitForEvent = async (api) => { api.on('eventOne', () => { return 'eventOne'; }) api.on('eventTwo', () => { return 'eventTwo'; }) api.on('eventThree', () => { return 'eventThree'; }) api.load(); } ``` What I am trying to do is setup event callbacks on the `api` variable inside the async function, trigger the `api.load()` function, and then return the event that happened first, in this case either `eventOne|eventTwo|eventThree` Problem is, this syntax is bad, and this example does not work. I couldn't find any way to achieve this using async/await and had to revert to promises like this: ``` const waitForEvent = (api) => { return new Promise(resolve) => { api.on('eventOne', () => { resolve('eventOne'); }) api.on('eventTwo', () => { resolve('eventTwo'); }) api.on('eventThree', () => { resolve('eventThree'); }) api.load(); } } ``` So my question is, can this be accomplished using async/await? Anyway this can be done using the new async/await es7 syntax?

Original source