简体   繁体   中英

nodejs event loop, how to use nextTick correctly

I'm trying to follow exercises from [node school][1]. There is an exercise where one needs to collect three streams and only print the output when all three streams are done. Without using any 3rd party module.

Can somebody please point out why my approach is not working? It gets stuck in an infinite loop:

var http = require('http');
var concat = require('concat-stream');

var count = 3;
var str1, str2, str3;

http.get(process.argv[2], function (response) {
  response.pipe(concat(function(data) {    
  str1 = data.toString();
  --count;
  }));
});

http.get(process.argv[3], function (response) {
  response.pipe(concat(function(data) {    
    str2 = data.toString();
    --count;
  }));
});

http.get(process.argv[4], function (response) {
  response.pipe(concat(function(data) {    
    str3 = data.toString();
    --count;
  }));
});

function foo() {
  if (count > 0) {     
    process.nextTick(foo);    
  } else {
     console.log(str1);
     console.log(str2);
     console.log(str3);
  }
};

foo();

http.get() callbacks can't run until the next tick of the event loop or later. process.nextTick() puts something right at the front of the event loop, ahead of the callbacks that are already there.

Your recursive routine never stops recursing because it's waiting for those callbacks to decrement the counter but they never fire.

It might work if you swap out process.nextTick() for setImmediate() . (I didn't test that, and if you do, hey, let me know if it works or not.)

But I would say just get rid of the recursion altogether. It's not needed. You can (for example) do something like this instead:

var count = 0;

var httpGet = function (index) {
  http.get(process.argv[2 + index], function (response) {

      // Do stuff here

      // This next bit will probably end up inside the callback provided to concat
      count++;
      if (count === 3) {
        // Print results here
      }
  })
};

for (var i = 0; i < 3; i++) {
  httpGet(i);
}

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