如何不使用setTimeout实现代码异步执行并达成指定输出?
异步编程实现指定输出顺序问题
现有代码如下:
const delayFunction = async () => { const startTime = new Date().getTime(); const duration = 10000; console.log('START') while (new Date().getTime() - startTime < duration) { // this loop runs for 10 seconds } console.log('STOP'); }; const starterFunction = async () => { console.log('1'); delayFunction(); console.log('2'); return 'DONE' }; console.log(starterFunction())
期望实现输出顺序:
1
2
DONE
START
STOP
尝试过改写delayFunction但未成功,代码如下:
const delayFunction = async () => { return new Promise((resolve,reject) => { const startTime = new Date().getTime(); const duration = 10000; console.log('START') while (new Date().getTime() - startTime < duration) { // this loop runs for 10 seconds } resolve(console.log('STOP')); }); };
问题原因
你之前的改写虽然用了Promise,但Promise的执行器(executor)函数是同步执行的,里面的while循环会阻塞主线程10秒,导致starterFunction里的2和返回的DONE都要等10秒后才会输出,完全不符合预期顺序。
正确实现方案
要实现目标顺序,核心是让delayFunction的逻辑完全异步,不阻塞当前执行栈。需要把同步阻塞的while循环替换为异步的setTimeout,让START和STOP的输出在当前所有同步代码执行完成后再触发。
const delayFunction = async () => { return new Promise((resolve) => { // 用0延迟将回调放入宏任务队列,等待当前执行栈清空后执行 setTimeout(() => { console.log('START'); // 模拟10秒延迟后输出STOP setTimeout(() => { console.log('STOP'); resolve(); }, 10000); }, 0); }); }; const starterFunction = async () => { console.log('1'); delayFunction(); // 不使用await,让函数在后台异步执行 console.log('2'); return 'DONE'; }; // 处理async函数的返回Promise,获取并输出DONE starterFunction().then(res => console.log(res));
执行顺序说明
- 调用
starterFunction(),首先输出1。 - 调用
delayFunction(),创建Promise后,将外层setTimeout回调放入宏任务队列,不阻塞后续代码。 starterFunction()继续执行,输出2,返回'DONE',Promise进入resolved状态。- 触发
then回调,输出DONE。 - 当前执行栈清空,宏任务队列中的外层
setTimeout回调执行,输出START,同时将内层10秒的setTimeout回调放入队列。 - 10秒后,内层
setTimeout回调执行,输出STOP并resolve Promise。
这样就能严格按照你期望的顺序输出。
内容的提问来源于stack exchange,提问作者Gagan
相关产品推荐
相关产品推荐

