Javascript: Simple Async Issue
Solution 1:
My understanding is that when using forEach()
in the browser, the expectation is that the callback will execute synchronously.
You could however revise your code as follows (provided the parent function is declared async
):
/*
The following changes require the calling function to be async
async function foo() { *//* Express iteration with for..of to achieve desired behavior */for(const client of sender.room()) {
const pokemon = awaitmakePokemon(client.getPokemon());
client.setPokemon(pokemon);
console.log('.1');
}
for(const client of sender.room()) {
console.log('.2');
client.emit('redirect', {
yourPokemon: client.getPokemon(),
theirPokemon: client.getOpponent().getPokemon()
});
}
/* } */
Alternatively, as Patrick Roberts points out, you could express this logic in part with Promise.all()
. One advantage with this approach is it allows multiple async
tasks (ie makePokemon
) to be dispatched at once rather than in a sequential fashion (as is the case above):
/* Map each client to a promise and execute all with Promise.all() */Promise.all(sender.room().map(async(client) => {
const pokemon = awaitmakePokemon(client.getPokemon());
client.setPokemon(pokemon);
console.log('.1');
}))
/* If all prior promises are resolved, continue with next iteration */
.then(() => {
for (const client of sender.room()) {
console.log('.2');
client.emit('redirect', {
yourPokemon: client.getPokemon(),
theirPokemon: client.getOpponent().getPokemon()
});
}
})
Solution 2:
Try waiting on all the promises:
const promises = sender.room().map(async (client) => {
const pokemon = awaitmakePokemon(client.getPokemon());
client.setPokemon(pokemon);
console.log('.1');
});
awaitPromise.all(promises);
sender.room().forEach(client => {
console.log('.2');
client.emit('redirect', {
yourPokemon: client.getPokemon(),
theirPokemon: client.getOpponent().getPokemon()
});
});
Solution 3:
forEach
won't wait for each loop to finish, it simply fires off a bunch of promises. If you want to explicitly wait for all those promises to finish before the second loop starts you can use map
followed by Promise.all
. The map
will return an array of promises. Promise.all
will explicitly pause until all promises in the given array have resolved. Does something like this work?
// use `map` and capture each promise in a new arrayconst pokemonPromises = sender.room().map(async (client) => {
const pokemon = awaitmakePokemon(client.getPokemon());
client.setPokemon(pokemon);
console.log('.1');
});
// explicitly wait for all promises to finish before continuing.awaitPromise.all(pokemonPromises);
// Continue with non async stuff
sender.room().forEach(client => {
console.log('.2');
client.emit('redirect', {
yourPokemon: client.getPokemon(),
theirPokemon: client.getOpponent().getPokemon()
});
});
Post a Comment for "Javascript: Simple Async Issue"