如何在循环内等待Promise完成(不使用async-await)
问题出在哪
你这段代码里的for循环是同步执行的,会一下子把所有wait(1000)都调用完——这些Promise几乎同时开始计时,1秒后一起完成,所以你会看到所有数字在1秒后一下子全出来,而不是每次等1秒再输出下一个。这就是为啥你感觉“只有第一次迭代在等”,实际上所有等待是并行触发的,总时长只有1秒,不是预期的5秒。
而用async-await的时候,await会暂停当前循环,等上一个wait完成后再执行下一次迭代,所以能实现每隔1秒输出一个数字的倒计时效果。
不用async-await的修复方法
如果想继续用Promise的then链式调用,得让每个wait在前一个完成后再触发,比如这样:
function wait(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds)) } function countDown(count) { let task = Promise.resolve(); for (let i = count; i > 0; i--) { // 把每个等待和输出任务串成链式执行 task = task.then(() => wait(1000)).then(() => console.log(i)); } return task; } countDown(5);
或者用递归实现,逻辑更直观:
function wait(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds)) } function countDown(count) { if (count <= 0) return; wait(1000) .then(() => { console.log(count); countDown(count - 1); }) .catch(error => console.log(error)); } countDown(5);
用async-await的正确写法(参考)
这是你说的能正常运行的版本,对比着看更清楚:
function wait(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds)) } async function countDown(count) { for (let i = count; i > 0; i--) { await wait(1000); console.log(i); } } countDown(5);
内容的提问来源于stack exchange,提问作者Tony Mike
相关产品推荐
相关产品推荐

