浏览器平台下一共有两个任务队列,一个是宏任务一个是微任务。
每执行一个宏任务之后就会立刻检查微任务队列setTimeout(() => {
console.log('s1')
Promise.resolve().then(() => {
console.log('p1')
})
Promise.resolve().then(() => {
console.log('p2')
})
})
setTimeout(() => {
console.log('s2')
Promise.resolve().then(() => {
console.log('p3')
})
Promise.resolve().then(() => {
console.log('p4')
})
})
打印结果:s1、p1、p2、s2、p3、p4
setTimeout(() => {
console.log('s1')
Promise.resolve().then(() => {
console.log('p2')
})
Promise.resolve().then(() => {
console.log('p3')
})
})
Promise.resolve().then(() => {
console.log('p1')
setTimeout(() => {
console.log('s2')
})
setTimeout(() => {
console.log('s3')
})
})
打印结果:p1、 s1、 p2、 p3、 s2、 s3
在浏览器平台下一共有两个任务队列,一个是宏任务一个是微任务。但在node下一共是有6个队列,如下

setInnediate中的回调在完成队列切换之前会清空微任务代码setTimeout(() => {
console.log('s1')
Promise.resolve().then(() => {
console.log('p1')
})
process.nextTick(() => {
console.log('t1')
})
})
Promise.resolve().then(() => {
console.log('p2')
})
console.log('start')
setTimeout(() => {
console.log('s2')
Promise.resolve().then(() => {
console.log('p3')
})
process.nextTick(() => {
console.log('t2')
})
})
console.log('end')
打印结果:start、end、p2、s1、t1、p1、s2、t2、p3
小结: process.nextTick是微任务,它的执行顺序优先于Promise.then。 而且在旧版中node的执行顺序是需要等宏任务队列执行完再执行微任务的也就是start、end、p2、s1、s2、t1、t2、p1、p3。 在新版node中改为与浏览器保持一致了
setTimeout不管是在浏览器平台下还是在node平台下,它的第二个参数如果不传默认是0,而传0的话会有些不稳定因素,就会造成延时可能在setImmediate之后的情况。当我们不停的执行下面这段代码时就会偶现immdieate现被打印的情况。
setTimeout(() => {
console.log('timeout')
})
setImmediate(() => {
console.log('immdieate')
})
但是如果将同样的代码放到文件读取之后的回调中顺序又会是始终一致。如下
const fs = require('fs')
fs.readFile('./m1.js', () => {
setTimeout(() => {
console.log('timeout')
}, 0)
setImmediate(() => {
console.log('immdieate')
})
})
原因是fs.readFile是一个poll事件队列。这个队列的执行顺序如下
