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?