我正在试验事件循环.首先,我从这个简单的代码开始,读取并打印文件的内容:
var fs = require('fs');
var PATH = "./.gitignore";
fs.readFile(PATH,"utf-8",function(err,text){
console.log("----read: "+text);
});
Run Code Online (Sandbox Code Playgroud)
然后我把它放到一个无限循环中.在这种情况下,永远不会执行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);
});
}
Run Code Online (Sandbox Code Playgroud)
所以,我想做一些事情,以便为I/O调用分配与循环交织在一起的处理时间.我尝试使用process.nextTick()但它不起作用:
while(true){
process.nextTick(function(){
fs.readFile(PATH,"utf-8",function(err,text){
console.log("----read: "+text)
});
});
}
Run Code Online (Sandbox Code Playgroud)
为什么它不起作用,我怎么能做到?
Jay*_*uri 24
因为你的while循环仍在运行.它只是在下一个滴答中无限添加要做的事情.如果你放手,你的节点进程会因内存不足而崩溃.
当您使用异步代码时,您的正常循环和控制结构往往会让您失望.原因是它们在事件循环的一个步骤中同步执行.直到某些事情再次产生对事件循环的控制,没有任何'nextTick'会发生.
可以这样想,当你的代码运行时,你在事件循环的Pass B中.你打电话的时候
process.nextTick(function foo() { do.stuff(); })'
Run Code Online (Sandbox Code Playgroud)
你要在开始传递事件循环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);
Run Code Online (Sandbox Code Playgroud)
(显然这是一个人为的例子,但你明白了)
这会导致每个"下一个文件"仅在完成前一个"nextTick"待办事项队列后才会被添加到"nextTick"待办事项队列中.
TL; DR:大多数时候,你不想在完成上一件事之前就开始做下一件事
希望有所帮助!
| 归档时间: |
|
| 查看次数: |
5397 次 |
| 最近记录: |