为何JavaScript中的await/async未按预期工作?示例代码求助
问题分析与解决方案
核心错误原因
你代码的问题在于**await 仅能等待 Promise 对象**,但setTimeout返回的是一个数字类型的定时器ID,并非Promise。因此await setTimeout(...)不会等待回调函数执行,而是直接将定时器ID包装为已完成的Promise返回,导致func1和func2会立即执行完毕,完全没等到内部的定时器回调触发。
为什么输出顺序不符合预期
因为mainFunc里的await func1()和await func2()都瞬间完成,代码直接走到console.log('execute completed')先输出该内容。之后2秒后func2的定时器触发,打印execute func2;再过3秒(累计5秒)func1的定时器触发,打印execute func1,这就是你看到的输出顺序。
修正后的代码
要让await等待异步操作完成,必须把setTimeout包装成Promise:
function func1() { return new Promise(resolve => { setTimeout(() => { console.log('execute func1'); resolve(); // 标记异步操作完成,通知await继续执行 }, 5000); }); } function func2() { return new Promise(resolve => { setTimeout(() => { console.log('execute func2'); resolve(); }, 2000); }); } async function mainFunc() { await func1(); // 等待func1的Promise完成 await func2(); // 等待func2的Promise完成 console.log('execute completed'); } mainFunc();
此时输出顺序会符合你的预期:
execute func1 execute func2 execute completed
关键概念补充
async函数的本质是让函数返回一个Promise,同时允许内部使用await语法。await会暂停当前async函数的执行,直到其后的Promise状态变为resolved,才会继续执行后续代码。- 如果
await后跟的不是Promise,JavaScript会自动将其包装为一个已resolved的Promise(比如await 123等价于await Promise.resolve(123)),因此不会产生任何等待效果。
内容的提问来源于stack exchange,提问作者BlueDolphin
相关产品推荐
相关产品推荐

