async/await环境下setTimeout未按预期延迟?如何实现Promise顺序执行?
问题原因
你当前代码的核心问题是三个Promise在函数执行初期就被实例化了,它们内部的setTimeout会立刻开始计时,和后续的await执行顺序完全无关。也就是说,p3的4秒、p2的3秒、p1的2秒定时器是同时启动的。当你await p3等待4秒完成后,p2和p1的定时器早就跑完了,所以后续的await p2和await p1会直接拿到已resolve的结果,自然会紧接着输出。
另外代码里还有个小笔误:console.lo(error)应该是console.log(error),这个也需要修正。
解决方案
要实现「前一个输出后再延迟对应时间执行下一个」的效果,必须让每个Promise的定时器在前一个任务完成后再启动。下面提供两种简洁的实现方式:
方式1:将Promise封装成函数,按需调用
把每个Promise的创建逻辑封装成函数,只有调用函数时才会创建Promise并启动定时器:
const ank = async() => { // 封装成函数,调用时才创建Promise并启动定时器 const createP1 = () => new Promise((resolve) => { setTimeout(() => resolve("resolved first"), 2000); }); const createP2 = () => new Promise((resolve) => { setTimeout(() => resolve("resolved second"), 3000); }); const createP3 = () => new Promise((resolve) => { setTimeout(() => resolve("resolved third"), 4000); }); console.log("p3 started"); const value3 = await createP3(); console.log(value3); console.log("p3 ended\n\n"); console.log("p2 started\n"); const value2 = await createP2(); console.log(value2); console.log("p2 ended\n\n\n"); console.log("p1 started\n"); const value1 = await createP1(); console.log(value1); console.log("p1 ended"); }; ank();
方式2:在await前才实例化Promise
如果不想封装函数,也可以把Promise的实例化代码移到对应await步骤的前面,确保定时器在前一个任务完成后才启动:
const ank = async() => { console.log("p3 started"); // 前序任务完成后,再实例化p3并启动4秒定时器 let p3 = new Promise((resolve) => { setTimeout(() => resolve("resolved third"), 4000); }); const value3 = await p3; console.log(value3); console.log("p3 ended\n\n"); console.log("p2 started\n"); // 同理,实例化p2并启动3秒定时器 let p2 = new Promise((resolve) => { setTimeout(() => resolve("resolved second"), 3000); }); const value2 = await p2; console.log(value2); console.log("p2 ended\n\n\n"); console.log("p1 started\n"); // 实例化p1并启动2秒定时器 let p1 = new Promise((resolve) => { setTimeout(() => resolve("resolved first"), 2000); }); const value1 = await p1; console.log(value1); console.log("p1 ended"); }; ank();
内容的提问来源于stack exchange,提问作者user19731938
相关产品推荐
相关产品推荐

