js await问题

      async function randomDelay(id)
        {
            const delay=Math.random()*1000;
            return new Promise((resolve)=>
            {
                setTimeout(()=>
                {
                    //console.log(`${id} 执行结束! 延迟${delay}`);
                    setTimeout(console.log,0,`${id} 执行结束! 延迟${delay}`)
                    resolve();
                },delay);
            })
        }       
        async function foo2()
        {
            const t0=Date.now();
            let p1= randomDelay(1);
            let p2= randomDelay(2);
            let p3= randomDelay(3);
            let p4= randomDelay(4);
            let p5= randomDelay(5);

            await p1;
            await p2;
            await p3;
            await p4;
            await p5;
            console.log(`${Date.now()-t0}毫秒`);
        }
        foo2();

image.png
console.log(${Date.now()-t0}毫秒);
这条为什么会先于最后一条setTimeout执行呢,
setTimeout(console.log,0,${id} 执行结束! 延迟${delay})
消息机制,出了包含setTimeout函数体应该立马打印了啊,为什么会有最后一条消息最后打印

阅读 2.6k
3 个回答
await p5; // 执行权交回(resolve())之前注册了一个setTimeout用于打印
console.log(`${Date.now()-t0}毫秒`); // p5 resolve之后执行权回到这里打印结果

// 没有后续内容了才轮到setTimeout

建议你看一下这篇文章 从setTimeout理解JS运行机制

JavasScript引擎是基于事件驱动和单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行程序,即主线程。JavaScript通过事件循环和浏览器各线程协调共同实现异步。同步可以保证顺序一致,但是容易导致阻塞;异步可以解决阻塞问题,但是会改变顺序性。

因为await是微任务,setTimeout是宏任务,微任务先于宏任务执行。

前面的就是微任务宏任务依次轮训,到await p5的时候setTimeout添加打印信息5到宏任务,await p5之后,添加打印信息${Date.now()-t0}毫秒到微任务

推荐问题