Open Quickeryi opened 7 years ago
我们都知道javascript是单线程机制,但是我们在开发过程中往往会写入很多的异步代码,那么js是如何进行任务调度的呢?
首先我们必须要清楚几个概念,这对于理解任务队列很有帮助
macro-task
task queue
js
setTimeout
setInterval
setImmediate
I/O
UI rendering
requestAnimationFrame
micro-task
process.nextTick
Promises.then
Object.observe
MutationObserver
整个过程用一张图就可以清晰展示
用代码说明一切
step1:console.log('main1'); step2:setTimeout(function() { console.log('setTimeout'); }, 0);
step3:requestAnimationFrame(function () { console.log('requestAnimationFrame'); });
step4:new Promise(function(resolve, reject) { console.log('promise'); resolve(); step5:}).then(function() { console.log('promise then'); });
step6:console.log('main2');
// output main1 promise main2 promise then requestAnimationFrame setTimeout
- 例1分析:首先**step1**、**step4**、**step6**处于主线程,所以它会归入第一个`macro-task-1`,所以首先调用,然后开始逐个调度`micro-task`(即:**step5**),而后开始调度第二个`macro-task-2`(即:**step3**)如此循环,直至结束! - 例子2 ```javascript step1:console.log('main1'); step2:process.nextTick(function () { console.log('process.nextTick1'); }); step3:setImmediate(function () { console.log('setImmediate'); }, 0); step4:setTimeout(function() { console.log('setTimeout'); step5:process.nextTick(function() { console.log('process.nextTick2'); }); }, 0); step6:new Promise(function(resolve, reject) { console.log('promise'); resolve(); step7:}).then(function() { console.log('promise then'); }); step8:console.log('main2'); // output main1 promise main2 process.nextTick1 promise then setTimeout process.nextTick2 setImmediate
macro-task-1
macro-task-2
macro-task-3
只有做到对js任务调度的机制了解,我们才能在开发中更好的掌控执行过程。
求解:在例子1中 同是宏任务为啥requestAnimationFrame 比 setTimeout 优先执行?
我们都知道javascript是单线程机制,但是我们在开发过程中往往会写入很多的异步代码,那么js是如何进行任务调度的呢?
概念
macro-task
:宏任务(也叫做task queue
)js
中,属于宏任务的有以下几种:setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
,requestAnimationFrame
micro-task
:微任务js
中,属于微任务的有以下几种:process.nextTick
,Promises.then
,Object.observe
,MutationObserver
macro-task
调度过程
实例
step3:requestAnimationFrame(function () { console.log('requestAnimationFrame'); });
step4:new Promise(function(resolve, reject) { console.log('promise'); resolve(); step5:}).then(function() { console.log('promise then'); });
step6:console.log('main2');
// output main1 promise main2 promise then requestAnimationFrame setTimeout
macro-task-1
首先执行,然后调度第一层循环的micro-task
(即:step2、step7),然后调度第二个macro-task-2
(即:step4),继续调度第二层循环micro-task
(即:step5),最后调度最后一个macro-task-3
(即:step3)小结
只有做到对
js
任务调度的机制了解,我们才能在开发中更好的掌控执行过程。参考