一、概念
- JavaScript是单线程的语言
- Event Loop是javascript的执行机制
- 宏任务:包括整体代码script,setTimeout,setInterval、setImmediate。
- 微任务:原生Promise(有些实现的promise将then方法放到了宏任务中)、process.nextTick、Object.observe(已废弃)、 MutationObserver 记住就行了。
- 遇到宏任务,先执行宏任务,将宏任务放入eventqueue,然后在执行微任务,将微任务放入eventqueue最骚的是,这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回掉函数,然后再从宏任务的queue上拿宏任务的回掉函数。
二、简单的例子
setTimeout(()=>{
console.log('setTimeout1')
},0)
let p = new Promise((resolve,reject)=>{
console.log('Promise1')
resolve()
})
p.then(()=>{
console.log('Promise2')
})
最后输出结果是Promise1,Promise2,setTimeout1
Promise参数中的Promise1是同步执行的 其次是因为Promise是microtasks(微任务),会在同步任务执行完后会去清空microtasks queues, 最后清空完微任务再去宏任务队列取值。
三、复杂的例子
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)
主线程注册Promise1为微任务、setTimeout1为宏任务-》执行微任务Promise1-》注册setTimeout2为宏任务-》执行setTimeout1-》执行微任务Promise2-》执行宏任务setTimeout2
四、终极例子
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')
})
})
答案:
1,7,6,8,2,4,3,5,9,11,10,12