了解Node.js事件循环。 process.nextTick()从未被调用过。为什么?

时间:2014-10-09 09:45:35

标签: node.js events

我正在尝试事件循环。首先,我从这个简单的代码开始,读取并打印文件的内容:

var fs = require('fs');
var PATH = "./.gitignore";

fs.readFile(PATH,"utf-8",function(err,text){
    console.log("----read: "+text);
});

然后我把它放到一个无限循环中。在这种情况下,永远不会执行readFile函数。如果我没有弄错的话,因为Node的单线程忙于迭代而不会让I / O调用被执行。

while(true){
    var fs = require('fs');
    var PATH = "./.gitignore";

    fs.readFile(PATH,"utf-8",function(err,text){
        console.log("----read: "+text);
    });
}

所以,我想做一些事情,以便为I / O调用分配与循环交织在一起的处理时间。我尝试使用process.nextTick()但它没有工作:

while(true){
    process.nextTick(function(){
        fs.readFile(PATH,"utf-8",function(err,text){
            console.log("----read: "+text)
        });
    });
}

为什么它不起作用,我怎么能做到?

1 个答案:

答案 0 :(得分:24)

因为你的while循环仍在运行。它只是在下一个滴答中无限添加要​​做的事情。如果你放手,你的节点进程会因内存不足而崩溃。

使用异步代码时,正常的循环和控制结构往往会让你失望。原因是它们在事件循环的一个步骤中同步执行。直到某些事情再次产生对事件循环的控制,没有任何'nextTick'会发生。

可以这样想,当你的代码运行时,你在事件循环的Pass B中。当你打电话

process.nextTick(function foo() { do.stuff(); })' 

在开始传递事件循环C之前,你要将foo添加到'要做的事情列表'中。每次调用nextTick时,都会向列表添加一个,但在同步代码完成之前,它们都不会运行。

您需要做的是在回调中创建“做下一件事”链接。想想链接列表。

// var files = your list of files;
function do_read(count) {
     var next = count+1;
     fs.readFile(files[count], "utf-8", function(err,text) {
         console.log("----read: " + text);

         if (next < files.length) {
            // this doesn't run until the previous readFile completes.
            process.nextTick(function() { do_read(next) });
         }
     });
}
// kick off the first one:
do_read(files[0], 0);

(显然这是一个人为的例子,但你明白了)

这会导致每个“下一个文件”仅在完成前一个“nextTick”待办事项队列后才会被添加到“nextTick”待办事项队列中。

TL; DR:大部分时间,在上一件事完成之前,你不想开始做下一件事

希望有所帮助!