Reputation: 616
Is it safe to use asyncs in javascript like this:
async coolFunction(users) {
const firstPromise = findPrivilegesInOneDbAsync();
const secondPromise = findPrivilegesInSecondDbAsync();
//LABEL_1
firstPromise.then(privilege=> {
users.forEach(user => {
if(user.privCode === privilege.code) {
user.privileges.push(privilege);
}
}
}
//LABEL_2
secondPromise.then(privilege=> {
users.forEach(user => {
if(user.altPrivCode === privilege.differentCode) {
user.privileges.push(privilege);
user.hasAlternativePrvis = true;
}
}
}
//LABEL_3
Promise.all([firstPromise, secondPromise]).then(() => {
console.log("DONE!");
//do something
})
}
The question is, is it guaranteed that LABEL_3 - Promise.all callback gonna execute after first and second promise (order in those two of course does not matter) callbacks are done?
Upvotes: 2
Views: 36
Reputation: 1075039
...is it guaranteed that LABEL_3 - Promise.all callback gonna execute after first and second promise (order in those two of course does not matter) callbacks are done?
Yes, it is. The fulfillment handlers on a promise are called in order of registration. Since your earlier ones are registered before your Promise.all
ones, they'll be run first.
Example:
function delay(ms, ...args) {
return new Promise(resolve => {
setTimeout(resolve, ms, ...args);
});
}
const promise = delay(800);
promise.then(() => {
console.log("first");
});
promise.then(() => {
console.log("second");
});
But it would probably be more idiomatic to use the promises returned by then
instead:
async coolFunction(users) {
const firstPromise = findPrivilegesInOneDbAsync();
const secondPromise = findPrivilegesInSecondDbAsync();
Promise.all([
firstPromise.then(privilege=> {
users.forEach(user => {
if(user.privCode === privilege.code) {
user.privileges.push(privilege);
}
}
},
secondPromise.then(privilege=> {
users.forEach(user => {
if(user.altPrivCode === privilege.differentCode) {
user.privileges.push(privilege);
user.hasAlternativePrvis = true;
}
}
}
])
.then(() => {
console.log("DONE!");
//do something
});
}
That would also have the advantage of waiting for any promises returned by those fulfillment handlers before executing the "done" logic.
It's probably worth noting that there's no reason for that method to be async
if you're going to do things in parallel like that and use .then
handlers rather than await
. You could do this, though, to keep the processing of the first two things in parallel but wait for them both to finish:
async coolFunction(users) {
const firstPromise = findPrivilegesInOneDbAsync();
const secondPromise = findPrivilegesInSecondDbAsync();
await Promise.all([
firstPromise.then(privilege=> {
users.forEach(user => {
if(user.privCode === privilege.code) {
user.privileges.push(privilege);
}
}
},
secondPromise.then(privilege=> {
users.forEach(user => {
if(user.altPrivCode === privilege.differentCode) {
user.privileges.push(privilege);
user.hasAlternativePrvis = true;
}
}
}
])
console.log("DONE!");
//do something
}
That would also wait for any promises returned by those fulfillment handlers before executing the "done" logic.
Upvotes: 3