Skip to content

process.nextTick

起因

在整理远古笔记的时候发现了问题

js
process.nextTick(() => {
  console.log('A')
  process.nextTick(() => {
    console.log('C')
  })
})

new Promise((resolve) => {
  console.log('Promise')
  resolve()
}).then(() => {
  console.log('then')
})
process.nextTick(() => {
  console.log('A')
  process.nextTick(() => {
    console.log('C')
  })
})

new Promise((resolve) => {
  console.log('Promise')
  resolve()
}).then(() => {
  console.log('then')
})

惯犯思维

Promise
A
then
C
Promise
A
then
C
  • Promise 的构造函数同步执行,在执行console.log('Promise')时,微任务queue只有function A
  • 执行resolve(),向微任务queue队尾插入then的回调()=> {console.log('then')},这时微任务queue长度为2。本轮事件循环宏任务执行结束,下面执行微任务
  • 先执行微任务function A,又产生了一个微任务function Cfunction C应该插入到当前微任务queue队尾, 微任务queue: [then, C]

微任务

process.nextTick 是一种特殊的微任务,它总是在当前阶段结束之前执行,即在事件循环的下一个阶段之前执行,而其他微任务会在下一个阶段执行(promise, queueMicrotask)

个人理解(臆想了一个队列)

process.nextTick 不像Promise.then()一样追加到微任务队尾,而是被放入一个单独的队列中,这个队列只存放 nextTick,并且这个队列的优先级比其他微任务要高。这意味着在当前事件循环中,所有的 nextTick 回调函数都会被执行完毕(包括在执行中产生的新的 nextTick),才会执行其他微任务。

js
process.nextTick(() => {
  console.log('A')
  process.nextTick(() => {
    console.log('C')
    process.nextTick(() => {
      console.log('D')
    })
  })
})

process.nextTick(() => {
  console.log('F')
  process.nextTick(() => {
    console.log('J')
  })
})

new Promise((resolve) => {
  console.log('Promise')
  resolve()
}).then(() => {
  console.log('then')
})

/** output
Promise
A
F
C
J
D
then
 */
process.nextTick(() => {
  console.log('A')
  process.nextTick(() => {
    console.log('C')
    process.nextTick(() => {
      console.log('D')
    })
  })
})

process.nextTick(() => {
  console.log('F')
  process.nextTick(() => {
    console.log('J')
  })
})

new Promise((resolve) => {
  console.log('Promise')
  resolve()
}).then(() => {
  console.log('then')
})

/** output
Promise
A
F
C
J
D
then
 */