是process.nextTick()立即执行

时间:2016-09-09 02:12:41

标签: node.js asynchronous

我让alrady观看了与事件循环工作相关的精彩视频 https://www.youtube.com/watch?v=8aGhZQkoFbQ

从某些阅读中,我认为process.nextTick会将回调放在事件队列的最开头。我也看到有人使用nextTick立即执行函数

我尝试编写一些代码来确认它

function printNextTick(s){
    process.nextTick(function(){
        console.log(s)
    })
}
for (var i=0;i<5;i++){
    printNextTick(i)
} 

我期望的是4,3,2,1,0,因为 nextTick将始终将回调放在队列的开头,脚本为“执行完成”,这意味着在“回调队列”期间不会执行回调,“4”是最后一次,所以在脚本完成后,“4”应该在队列的第一个位置,这就是为什么我期望“4”首先出现

但这不正确

================================更新============== ====================== 这里是新代码

function printNextTick(s){
    process.nextTick(function(){
        console.log("nextTick : "+s)
    })
}
function printTimeout(s){
    setTimeout(function(){
        console.log("timeout : "+s)
    },0)
}
for (var i=0;i<5;i++){
    printTimeout(i)
}
for (var i=0;i<5;i++){
    printNextTick(i)
}
//nextTick : 0
//nextTick : 1
//nextTick : 2
//nextTick : 3
//nextTick : 4
//timeout : 0
//timeout : 1
//timeout : 2
//timeout : 3
//timeout : 4

想知道为什么有些人会将nextTick视为immediate原来,我认为nextTick会在event queue的开头放回调而不是正常结束,现在,我认为nextTick的队列优先级高于其他队列,至少高于timeout的队列

==================更新===============

上面不是真的! 下面代码的结果是非常不可预测的

function printNextTick(s){
    process.nextTick(function(){
        console.log("nextTick : "+s)
    })
}

function printTimeout(s){
    setTimeout(function(){
        console.log("timeout : "+s)
        for (var i=0;i<5;i++){
            printNextTick(i)
        }

    },0)
}
for (var i=0;i<5;i++){
    printTimeout(i)
}

3 个答案:

答案 0 :(得分:1)

您传递给process.nextTick()的任何回调都附加到内部队列,该内部队列被刷新(最大IIRC以便不会使事件循环的其余部分完全饿死),按顺序,在&#34;下一个刻度。&#34;因此,在您的示例中,您首先附加一个打印'0'的回调,然后打印一个打印'1'等的回调。然后按顺序执行这些回调,您会看到按数字顺序打印的数字。

答案 1 :(得分:0)

要理解nextTick和setTimeout之间的区别,请考虑我的setTimeout实现:

function setTimeout2(callback, ms) {
    var t = process.hrtime(), 
    _next = () => 
        process.nextTick(process.hrtime(t)[0] > !!ms?callback:_next);
    _next();
}

function printNextTick(s){
    process.nextTick(() => console.log('n'+s))
}

function printTimeout(s){
    setTimeout2(() => {
        console.log('t'+s);
        for (var i=0;i<5;i++)
            printNextTick(s+':'+i);
    });
}

for (var i=0;i<5;i++)
    printTimeout(i);

它的行为与setTimeout非常相似,但效率较低。要回答你的问题,不,process.nextTick(回调)会将回调附加到nextTick队列。如果diff&gt; setTimeout(callback,ms)也将其回调附加到nextTick队列。 ms(不是&gt; = ms)。

答案 2 :(得分:0)

只是想知道为什么有些人会立即将nextTick视为

From the documentation:

  

process.nextTick()会立即在同一阶段触发   setImmediate()在接下来的迭代中触发或者&#39; tick&#39;事件循环   实质上,应该交换名称。 process.nextTick()比setImmediate()更快地触发,但这是过去的一个不太可能改变的工件。进行此切换会破坏npm上的大部分包。每天都会添加更多新模块,这意味着我们每天都在等待更多潜在的破损。

最初,我认为nextTick会在事件队列的开头放回调而不是正常结束,现在,我认为nextTick的队列优先级高于其他队列,至少高于队列超时

From process docs:

  

process.nextTick()在任何其他I / O事件(包括计时器)之前运行