Node.js 0.10版本今天发布,并引入了setimmediation。API更改文档建议在进行递归nextTick调用时使用它。
根据MDN的说法,它似乎与process.nextTick非常相似。
什么时候应该使用nextTick,什么时候应该使用setimmediation ?
Node.js 0.10版本今天发布,并引入了setimmediation。API更改文档建议在进行递归nextTick调用时使用它。
根据MDN的说法,它似乎与process.nextTick非常相似。
什么时候应该使用nextTick,什么时候应该使用setimmediation ?
当前回答
简单来说,process.NextTick()将在事件循环的下一个tick执行。但是,setimmediation基本上有一个单独的阶段,该阶段确保在setimmediation()下注册的回调只会在IO回调和轮询阶段之后被调用。
请参考这个链接了解详细解释: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and-its-metrics-c4907b19da4c
其他回答
你永远不应该使用process中断cpu负荷大的操作。
你不应该使用process.nextTick()中断这样的工作。这样做将导致一个永远不会清空的微任务队列——您的应用程序将永远被困在同一个阶段! ——托马斯·亨特使用Node.js的分布式系统
事件循环的每个阶段包含几个回调:
一旦process.nextTick()被触发,它将始终保持在相同的阶段。
例子
const nt_recursive = () => process.nextTick(nt_recursive);
nt_recursive(); // setInterval will never run
const si_recursive = () => setImmediate(si_recursive);
si_recursive(); // setInterval will run
setInterval(() => console.log('hi'), 10);
在本例中,setInterval()表示应用程序执行的一些异步工作,例如响应传入的HTTP请求。
一旦nt_recursive()函数运行,应用程序就会得到一个永远不会清空的微任务队列,异步工作也永远不会得到处理。
但是替代版本si_recursive()没有同样的副作用。
在检查阶段中调用setimmediation()会将回调添加到下一个事件循环迭代的检查阶段队列,而不是当前阶段的队列。
Case可能使用process.nextTick
使函数处理都异步进行。
function foo(count, callback) {
if (count <= 0) {
return process.nextTick(() => callback(new TypeError('count > 0')));
}
myAsyncOperation(count, callback);
}
——托马斯·亨特使用Node.js的分布式系统
在这种情况下,使用setimmediation()或process.nextTick()都可以;只是要确保你不会意外地引入递归。
在回答的评论中,它没有明确地说明nextTick从Macrosemantics转移到Microsemantics。
在节点0.9之前(引入setimmediation时),nextTick在下一个调用堆栈的开始操作。
从节点0.9开始,nextTick操作在现有调用堆栈的末尾,而setimmediation操作在下一个调用堆栈的开始
查看https://github.com/YuzuJS/setImmediate获取工具和详细信息
如果您希望将函数置于已经在事件队列中的任何I/O事件回调之后,请使用setimmediation。使用过程。nextTick可以有效地将函数排在事件队列的头部,以便在当前函数完成后立即执行。
因此,在试图使用递归分解长时间运行的cpu绑定作业的情况下,您现在会希望使用setimmediation而不是process。nextTick将在下一个迭代中排队,否则任何I/O事件回调都没有机会在迭代之间运行。
举个例子:
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
我希望这能帮助你理解其中的区别。
更新:
使用process.nextTick()延迟的回调在任何其他I/O之前运行 事件被触发,而使用setimmediation(),执行被排队 在已经在队列中的任何I/O事件后面。 Node.js设计模式,作者Mario Casciaro(可能是关于Node.js /js最好的书)
简单来说,process.NextTick()将在事件循环的下一个tick执行。但是,setimmediation基本上有一个单独的阶段,该阶段确保在setimmediation()下注册的回调只会在IO回调和轮询阶段之后被调用。
请参考这个链接了解详细解释: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and-its-metrics-c4907b19da4c