macrotasks(task):
setTimeout, setInterval, setImmediate, I/O, UI rendering
宏任务,每次执行栈执栈的代码(包括每次从事件队列中获取一个事件回调并放在执行栈中执行),包括主代码块(同步)、setTimeout、setInterval(异步)等
microtasks(jobs):
process.nextTick, Promise, MutationObserver
微任务,在task执行结束后立即执行的任务,包括promise的then、process.nextTick(微任务队列,优先级更高)等
运行机制:
1.执行一个宏任务(栈中没有就从事件队列中获取),执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
2.宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
3.当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
4.渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
注意点:
Promise的函数代码的异步任务会优先于setTimeout的延时为0的任务先执行。
原因是任务队列分为 macrotasks 和 microtasks, 而promise中的then方法的函数会被推入到microtasks队列中,而setTimeout函数会被推入到macrotasks
任务队列中,在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。
也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。而事件循环每次只会入栈一个macrotask,主线程执行完成该任务后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。
网友评论