在查看解析之前,思考一下下面的代码会输出什么内容?
|
|
解析:
setTimeout
里的内容进入 Event Loop 的 macrotask,在下一个 Event Loop 中执行,所以暂不执行.resolve
中的任务会进入 Event Loop 的 microtask,所以最先输出 2 和 3.resolve
后 then
中的回调,故输出 4 .setTimeout
的回调输出 1.其中要注意的是,Promise.then()里面的回调属于 microtask, 会在当前 Event Loop 的最后执行, 而
setTimeout
内的回调属于 macrotask, 会在下一个 Event Loop 中执行.
所以正确输出顺序是:
|
|
一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。
任务队列又分为macro-task(宏任务)与micro-task(微任务)。
macro-task大概包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。
micro-task大概包括: process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)
事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(整体代码)开始第一次循环。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task,这样一直循环下去。