setImmediate vs. nextTick

2022-08-29 23:38:44

Node.js版本0.10今天发布并推出。API 更改文档建议在执行递归调用时使用它。setImmediatenextTick

MDN的说法来看,它似乎与非常相似。process.nextTick

我应该什么时候使用,什么时候应该使用?nextTicksetImmediate


答案 1

如果要将函数排队到事件队列中已有的任何 I/O 事件回调后面,请使用此选项。用于在事件队列的头部有效地对函数进行排队,以便在当前函数完成后立即执行。setImmediateprocess.nextTick

因此,如果您尝试使用递归来分解长时间运行的 CPU 密集型作业,您现在希望使用而不是将下一次迭代排队,否则任何 I/O 事件回调都不会有机会在迭代之间运行。setImmediateprocess.nextTick


答案 2

举例来说:

import fs from 'fs';
import http from 'http';
    
const options = {
  host: 'www.stackoverflow.com',
  port: 80,
  path: '/index.html'
};

describe('deferredExecution', () => {
  it('deferredExecution', (done) => {
    console.log('Start');
    setTimeout(() => console.log('setTimeout 1'), 0);
    setImmediate(() => console.log('setImmediate 1'));
    process.nextTick(() => console.log('nextTick 1'));
    setImmediate(() => console.log('setImmediate 2'));
    process.nextTick(() => console.log('nextTick 2'));
    http.get(options, () => console.log('network IO'));
    fs.readdir(process.cwd(), () => console.log('file system IO 1'));
    setImmediate(() => console.log('setImmediate 3'));
    process.nextTick(() => console.log('nextTick 3'));
    setImmediate(() => console.log('setImmediate 4'));
    fs.readdir(process.cwd(), () => console.log('file system IO 2'));
    console.log('End');
    setTimeout(done, 1500);
  });
});

将给出以下输出

Start // synchronous
End // synchronous
nextTick 1 // microtask
nextTick 2 // microtask
nextTick 3 // microtask
setTimeout 1 // macrotask
file system IO 1 // macrotask
file system IO 2 // macrotask
setImmediate 1 // macrotask
setImmediate 2 // macrotask
setImmediate 3 // macrotask
setImmediate 4 // macrotask
network IO // macrotask

我希望这可以帮助理解其中的区别。

更新:

在触发任何其他 I/O 事件之前,将延迟的回调与 run 一起延迟,而使用 setImmediate(), 执行将排队在队列中已有的任何 I/O 事件之后。process.nextTick()

Node.js Design Patterns,作者:Mario Casciaro(可能是关于node.js/js的最佳书籍)