整个js这种运行机制又称为Event Loop(事件循环)node
上代码感觉一下浏览器
setTimeout(() => {
console.log(1)
Promise.resolve(3).then(data => console.log(data))
}, 0)
setTimeout(() => {
console.log(2)
}, 0)
//浏览器 1 3 2
//node 1 2 3
复制代码
首先就是执行时会有一个栈 而后有一个事件队列和微任务空间(本身命名的)bash
当咱们的代码从上到下同步执行时,遇到setTimeout就记时,当时间到时就把此事件放到事件队列中,遇到微任务就把微任务放到微任务空间,代码会继续向下执行,直到同步代码执行完毕。异步
完毕后,会看看微任务空间中有没有微任务,有就把微任务空间中的微任务所有执行,而后去队列中取咱们的事件执行,执行时如有微任务继续放到微任务空间,当此事件执行完毕,还会把微任务空间中的微任务所有执行完毕,而后再去取队列中的异步任务。。。。反复循环oop
有图有真相(是否是很丑!丑也别说出来)ui
想上个丑图spa
setImmediate 设计在poll阶段完成时执行,即check阶段; setTimeout 设计在poll阶段为空闲时,且设定时间到达后执行;但其在timer阶段执行 其两者的调用顺序取决于当前event loop的上下文,若是他们在异步i/o callback以外调用(在i/o内调用由于下一阶段为check阶段),其执行前后顺序是不肯定的,须要看loop的执行前的耗时状况设计
废话很少说,上代码code
setImmediate(() => {
console.log('setImmediate1')
setTimeout(() => {
console.log('setTimeout1')
}, 0);
})
setTimeout(()=>{
console.log('setTimeout2')
setImmediate(()=>{
console.log('setImmediate2')
})
},0);
//首先setImmediate和setTimeout执行顺序不固定
//因此setImmediate1和setTimeout2,打印顺序不定
//假设 setImmediate1先打印 有两种顺序
//1.执行顺序是 setImmediate1 setTimeout2 setTimeout1 setImmediate2
//2.执行顺序是 setImmediate1 setTimeout2 setImmediate2 setTimeout1
// 1.setImmediate1打印后把setTimeout1放进timer队列 而后执行setTimeout2 这时候把setImmediate2放进check队列中 打印setTimeout2 发现timer中还有setTimeout1 他就会把timer对列中的执行完 才会执行下一队列的代码
//而后打印setTimeout1, 切换对列到check 打印setImmediate2
//2. setImmediate1打印后把setTimeout1放进timer队列 而后执行setTimeout2 这时候把setImmediate2放进check队列中 打印setTimeout2 这个时候node执行过快setTimeout1尚未到时间,因此切换对列执行setImmediate2 而后是setTimeout1
//setTimeout第二个参数虽然是0,可是都有默认时间通常是4ms左右
复制代码
再来一题cdn
setImmediate(() => {
console.log('setImmediate1')
setTimeout(() => {
console.log('setTimeout1')
}, 0);
})
setTimeout(()=>{
console.log('setTimeout2')
process.nextTick(()=>console.log('nextTick'))
setImmediate(()=>{
console.log('setImmediate2')
})
},0);
//假设setImmediate1先
//setImmediate1 setTimeout2 setTimeout1 nextTick setImmediate2
//setImmediate1 setTimeout2 nextTick setImmediate2 setTimeout1
//微任务会在切换对列时执行 上面从timer对列切换到check对列时nextTick执行
//上面一题明白了这一个也明白了
复制代码
再来一题
let fs = require('fs');
fs.readFile('./1.txt',function () {
console.log(1);
setTimeout(() => {
console.log('setTimeout')
}, 0);
setImmediate(() => {
console.log('setImmediate')
});
});
//顺序固定 1 setImmediate setTimeout
// 为何呢?看上面的图 首先readFile确定是poll对列 执行时把setTimeout setImmediate放到各自队列 而后按上下顺序查找对列 查找到check队列发现有 就把setImmediate打印出 而后顺序检查下一队列close没有 循环 再次从上往下找 直到timer打印setTimeout
复制代码
以上内容是本人试出来的 mac vscode
Promise.resolve('123').then(res=>{
console.log(res);
})
process.nextTick(() => console.log('nextTick'))
//顺序 nextTick 123
//很明显 nextTick快
复制代码