简体   繁体   中英

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

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM