简体   繁体   中英

Semaphores in node.js - using a counter variable

I have been studying JavaScript for a while now and I can't seem to understand why the following code won't work. I tried to make the main execution line wait for the end of the asynchronous function call using a semaphore-ish technique. You can have a look at the code here:

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");

Any help would be appreciated, thanks.

The problem is a misunderstanding of the event loop.

In short, JavaScript has an event queue which all asynchronous events are placed in to. Whenever the JS engine isn't currently busy ie no code is currently executing, it extracts the next event off of the event queue.

Your asynchronous handlers have been pushed on to the event queue but your while loop is preventing execution from ever ending so the engine never has a chance to run the next thing in the queue.

One way of imagining it is this:

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM