当我运行以下代码时:
b = async attempt => {
if (attempt == 5) {
return;
}
console.log("Starting attempt:", attempt);
b(attempt + 1).then(() => {
console.log("Finished attempt:", attempt);
});
};
b(0);
输出为:
Starting attempt: 0
Starting attempt: 1
Starting attempt: 2
Starting attempt: 3
Starting attempt: 4
Finished attempt: 4
Finished attempt: 3
Finished attempt: 2
Finished attempt: 1
Finished attempt: 0
但是,我想在每次递归调用之前调用另一个诺言a
,如下所示:
a = Promise.resolve();
b = async attempt => {
if (attempt == 5) {
return;
}
console.log("Starting attempt:", attempt);
a.then(() => {
b(attempt + 1);
}).then(() => {
console.log("Finished attempt:", attempt);
});
};
b(0);
现在输出为:
Starting attempt: 0
Starting attempt: 1
Starting attempt: 2
Finished attempt: 0
Starting attempt: 3
Finished attempt: 1
Starting attempt: 4
Finished attempt: 2
Finished attempt: 3
Finished attempt: 4
如何修改第二个代码块以确保输出与第一个代码块相同?
答案 0 :(得分:1)
如果我正确理解了您的问题,则问题是由嵌套的promise和对异步函数(即b(attempt + 1)
的调用)引起的,而这并不阻止封闭函数的执行。反过来,这会产生无序且意外的日志记录结果。
考虑通过b()
对return
的承诺来修订对b(attempt + 1);
的调用,以确保在console.log("Finished attempt:", attempt)
完成后执行以下日志:b()
完成:
const a = Promise.resolve();
const b = async attempt => {
if (attempt == 5) {
return;
}
console.log("Starting attempt:", attempt);
await a.then(() => {
/*
Return the project of b() here, has similar effect
to that of await keyword
*/
return b(attempt + 1);
}).then(() => {
console.log("Finished attempt:", attempt);
});
};
b(0);
答案 1 :(得分:1)
您通过不返回内部承诺a.then(() => {b(attempt + 1);})
破坏了承诺链。添加return语句应该会有所帮助。
我也建议不要将async/await
语法与.then
和回调一起使用。
以下代码看起来更“同步”,并且可以解决问题。
const a = Promise.resolve();
const b = async attempt => {
if (attempt == 5) {
return;
}
console.log("Starting attempt:", attempt);
await a
await b(attempt + 1)
console.log(`Finished attempt: ${attempt}`)
};
b(0);
答案 2 :(得分:1)
您忘记了return
您正在创建的承诺链:
const b = attempt => {
if (attempt == 5) {
return Promise.resolve();
}
console.log("Starting attempt:", attempt);
const a = Promise.resolve();
return a.then(() => {
//^^^^^^
return b(attempt + 1);
// ^^^^^^
}).then(() => {
console.log("Finished attempt:", attempt);
});
};
b(0).then(() => {
console.log("done");
});
只有使用那些return
,函数的调用者才能等待promise。您的第一个片段有相同的问题。如果您省略了async
关键字,那就更加明显了,这样很显然b()
并没有返回承诺。
如果您想使用async
/ await
,则代码应如下所示:
const b = async attempt => {
if (attempt == 5) {
return;
}
console.log("Starting attempt:", attempt);
await Promise.resolve();
//^^^^^
await b(attempt + 1);
//^^^^^
console.log("Finished attempt:", attempt);
};
b(0).then(() => {
console.log("done");
});