async/await函数未等待setTimeout完成,执行顺序不符合预期
问题原因与解决方法
没错,这确实是setTimeout导致的问题!让我给你拆解一下为什么会出现这种顺序颠倒的情况:
你的hideMoveUI和startAnim函数虽然用了setTimeout做异步操作,但它们本身没有返回Promise对象。而await关键字只能等待Promise(或者实现了thenable接口的对象)完成,当你await一个普通函数时,它会直接把函数的返回值(这里是undefined)当成已经resolved的Promise,根本不会等待setTimeout里的代码执行完毕。
所以实际的执行流程是这样的:
- 调用
printAll(),里面先执行await hideMoveUI()——但hideMoveUI立刻返回undefined,await直接跳过,马上执行下一行await startAnim(); startAnim同样立刻返回undefined,await也跳过,printAll执行完毕;- 此时两个
setTimeout都在后台等待,startAnim里的延迟只有500ms,比hideMoveUI的3000ms短,所以先输出startAnim,3秒后才输出hideMoveUI。
解决方法:让异步函数返回Promise
只需要把hideMoveUI和startAnim改成返回Promise的形式,await就能正确等待它们的异步操作完成了:
async function printAll() { await hideMoveUI(); await startAnim(); } hideMoveUI = () => { return new Promise(resolve => { setTimeout(() => { console.log('hideMoveUI'); resolve(); // 异步操作完成后调用resolve,告知await可以继续 }, 3000); }); } startAnim = () => { return new Promise(resolve => { setTimeout(() => { console.log('startAnim'); resolve(); }, 500); }); } printAll();
现在执行顺序就会完全符合预期:先等待3秒输出hideMoveUI,再等待500ms输出startAnim。
另外,你也可以把这两个函数写成async函数的形式(本质还是返回Promise),代码会更简洁:
hideMoveUI = async () => { await new Promise(resolve => setTimeout(resolve, 3000)); console.log('hideMoveUI'); } startAnim = async () => { await new Promise(resolve => setTimeout(resolve, 500)); console.log('startAnim'); }
这样await hideMoveUI()同样会等待内部的异步操作完成后,再继续执行下一行代码。
内容的提问来源于stack exchange,提问作者daniel aagentah
相关产品推荐
相关产品推荐

