JS中的任务可分为以下两类
·macro-task(宏任务):包括整体代码script,setTimeout,setInterval ·micro-task(微任务):Promise.then,process.nextTick
JS执行过程优先执行所有宏任务,之后执行微任务,之后继续新的宏任务,之后又是微任务一直循环执行。
console.log('start'); new Promise(function(resolve) { console.log('promise'); resolve(); }).then(function() { console.log('then'); }) console.log('end');依次输出start->promise->end->then 遇见第一个console属于宏任务直接输出,遇见promise属于宏任务直接输出,遇见then输入微任务放入微任务队列中,遇见最后的console属于宏任务直接输出,最后执行微任务队列中的then。
console.log('start'); new Promise(function(resolve) { console.log('promise1'); resolve(); }).then(function() { new Promise(function(resolve) { console.log('promise2'); resolve(); }).then(function() { console.log('then'); }) }) console.log('end');如果理解的话你可以尝试思考下上面代码会的输出顺序
start->promise1->end->promise2->then
现在我们说JS处理异步的方式: ·同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。 ·当指定的事情完成时,Event Table会将这个函数移入Event Queue。 ·主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。 ·上述过程会不断重复。
console.log('start'); setTimeout(() => { console.log('setTimeout'); }, 0); console.log('end');依次输出:start->end->setTimeout 遇见第一个console属于同步任务直接执行,遇见第二个setTimeout属于异步任务,进入Event Table并注册函数,0秒后推入Event Queue。遇见下一个console直接输出,同步任务执行完后。主进程执行Event Queue中的回调函数输出setTimeout
知道了异步的执行方式,那异步与微任务同时出现的情况也可以分析。
console.log('start'); new Promise(function(resolve) { setTimeout(() => { console.log('setTimeout1'); }, 0); resolve(); }).then(function() { console.log('then'); setTimeout(() => { console.log('setTimeout2'); }, 0); }) setTimeout(() => { console.log('setTimeout3'); }, 0); console.log('end');依次输出:start->end->then->setTimeout1->setTimeout3->setTimeout2 遇见console.log(‘start’)属于宏任务/同步任务直接执行,遇见Promise中的setTimeout属于宏任务/异步任务,进入Event Table并注册函数,0秒后推入Event Queue,遇见then,属于微任务推入微任务队列中,遇见最后一个setTimeout属于宏任务/异步任务,进入Event Table并注册函数,0秒后推入Event Queue,遇见console.log(‘end’)属于宏任务/同步任务之间执行,然后执行微任务中的then函数中的console.log(‘then’);属于宏任务/同步任务直接执行,然后setTimeout,进入Event Table并注册函数,0秒后推入Event Queue,然后依次执行进入Event Queue的三个console。
console.log('start'); new Promise(function(resolve) { setTimeout(() => { console.log('setTimeout1'); }, 0); resolve(); }).then(function() { new Promise(function(resolve) { console.log('then1'); setTimeout(() => { console.log('setTimeout2'); }, 0); resolve(); }).then(function() { console.log('then2'); setTimeout(() => { console.log('setTimeout3'); }, 0); }) }) setTimeout(() => { console.log('setTimeout4'); }, 0); console.log('end');如果理解可以理解可以尝试上面较为复杂的代码 依次输出:start->end->then1->then2->setTimeout1->setTimeout4->setTimeout2->setTimeout3