每个异步调用和承诺的特定任务等待所有调用



在javascript中使用异步安全吗?

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

问题是,是否可以保证在第一个和第二个承诺(这两个中的顺序当然无关紧要(回调之后执行LABEL_3 - Promise.all 回调

...是否可以保证 LABEL_3 - Promise.all 回调将在第一个和第二个 promise 之后执行(这两个回调中的顺序当然无关紧要(回调完成?

是的,它是。承诺的履行处理程序按注册顺序调用。由于您较早的Promise.all个在 之前注册,因此它们将首先运行。

例:

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

但是,改用then返回的承诺可能会更惯用:

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

这也具有在执行"完成"逻辑之前等待这些履行处理程序返回的任何承诺的优点。


可能值得注意的是,如果您要像这样并行执行操作并使用.then处理程序而不是await,则没有理由async该方法。不过,您可以这样做以并行处理前两件事,但等待它们完成:

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
}

这也将在执行"完成"逻辑之前等待这些履行处理程序返回的任何承诺。

最新更新