1.js是单线程语言,在主线程中,代码的执行是顺序执行的
js中还会有很多异步操作,例如setTimeout,setInterval,promise等等,首先主线程代码先执行,然后执行微任务,再执行宏任务。
2.哪些属于宏任务,哪些属于微任务?
宏任务:包括整体代码script,setTimeout,setInterval等
微任务:promise.then的回调函数,promise.nextTick,async 函数await下面的代码
3.js执行的时候:
第一步:js
解释器识别所有 js
代码,将同步的代码放到主线程执行;异步的代码放到Event Table(事件列表)
执行。这也是第一次宏任务执行完毕!
第二步:接下来执行所有的微任务。
之后一直循环第一步,第二步,也就是常说的Event Loop(事件循环)
事件循环可以用下面这张流程图理解
为了理解来分析一段较复杂的代码:
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
第一轮:
整体代码script作为第一个宏任务执行,首先1会被打印出来,然后第一个setTimeout被放到宏任务列,nextTick被放到微任务列,new Promise会首先打印7,然后第一个then会被放到微任务列,第二个setTImeout被放到宏任务列。第一轮宏任务结束,看看微任务列是否有微任务有的话,全部执行完,nextTick1,打印6,then1,打印8,第一轮结束,打印了1,7,6,8
第二轮:
首先执行第一个setTImeout,首先打印2,然后nextTick会被放大微任务列,promise打印4,then放进微任务列,然后第二个宏任务结束,执行微任务,打印3和5,第二轮打印了2,4,3,5
第三轮:
执行第二个setTimeout,首先打印9,然后nextTick会被放大微任务列,promise打印11,then放进微任务列,然后第二个宏任务结束,执行微任务,打印10和12,第二轮打印了9,11,10,12
所以打印顺序为1,7,6,8,2, 4,3,5,9,11,10,12