javascript - node.js 中的信号量 - 使用计数器变量

标签 javascript node.js asynchronous concurrency semaphore

我研究 JavaScript 已经有一段时间了,我似乎无法理解为什么下面的代码不起作用。我尝试使用类似信号量的技术让主执行线等待异步函数调用结束。您可以在此处查看代码:

var fs = require("fs");
var data = "";
var asyncDone = false;
var fstream = fs.createReadStream("text.txt");
fstream.setEncoding("utf-8");

fstream.on("data", function (chunk) {
    data += chunk;
});
fstream.on("end", function() {
    console.log("reading done");
    console.log(data);
    asyncDone = true;
});

while (! asyncDone) { }
console.log("program terminating");

如有任何帮助,我们将不胜感激。

最佳答案

问题是对event loop.的误解

简而言之,JavaScript 有一个事件队列,所有异步事件都放在其中。只要 JS 引擎当前不忙,即当前没有代码正在执行,它就会从事件队列中提取下一个事件。

您的异步处理程序已被推送到事件队列,但您的 while 循环阻止执行永远结束,因此引擎永远没有机会运行队列中的下一个事件。

一种想象方式是这样的:

var eventQueue = [];
function addToQueue(f) {
  eventQueue.push(f);
}
function runNext() {
  if (eventQueue.length) {
    var f = eventQueue.shift();
    f();
    runNext();
  }
}    

addToQueue(function() {
  // Note that in reality the binding occurs synchronously,
  // it's just that the callback will occur asynchronously
  fstream.on('data', function(chunk) {
    // ...
  });
});

while (!asyncDone) { }
runNext();

关于javascript - node.js 中的信号量 - 使用计数器变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42027584/

相关文章:

javascript - knockout observableArray 未正确绑定(bind)

javascript - 更改节点列表中的所有元素

javascript - 我应该如何循环依赖于前一个循环值的异步函数?

c# - 如果使用的库不支持异步等待,在哪里使用 Task.Run

javascript - 静态 Promise.resolve()/reject() 始终被解释为resolve()

javascript - 如何打开 Firebase Javascript 客户端的登录?

javascript - 如何在不同页面之间创建动画页面转换?

javascript - Nodejs运行但没有输出 'Hello'(使用模块)

javascript - 如何设置babel导出到es4 javascript?

javascript - 当 gulpfile 中不存在用户要求的任务时运行特定任务