Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For-loop and async callback in node.js?

Tags:

I'm new to JavaScript and to node.js. I want to loop through a directory and add all file stat (not other directories) to an array. As you see below there is a problem with my code since the callback will probably get called after the for loop has finished so using the "i"-variable in the callback method will not work. But how should the code look so that the below snippet works? Does it have something to do with closures?

Thanks for help!

    fs.readdir(SYNCDIR, function(err1, files) {         var filesOnly = [];          if(!err1) {              for(var i = 0; i < files.length; i++) {                  var imgFilePath = SYNCDIR + '/' + files[i];                 fs.stat(imgFilePath, function(stat){                      if (stat.isFile()){                         filesOnly[i] = stat; // This will not be correct since the for-loop has finished                     }                 });              }         }     }); 
like image 637
exkoria Avatar asked Sep 01 '11 09:09

exkoria


People also ask

Can we use async in for loop?

Combining async with a for (or a for...of ) loop is possibly the most straightforward option when performing asynchronous operations over array elements. Using await inside a for loop will cause the code to stop and wait for the asynchronous operation to complete before continuing.

How do I use async await with for loop?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure. But you can't await with Array.

What are async callbacks?

Asynchronous callbacks are functions passed to another function that starts executing code in the background. Typically, when the code in the background finishes, the async callback function is called as a way of notifying and passing on data to the callback function that the background task is finished.


1 Answers

You are right about needing to use a closure. You should wrap the contents of the for loop in a self-invoking function to preserve the value of i for each iteration.

fs.readdir(SYNCDIR, function(err1, files) {     var filesOnly = [];      if(!err1) {          for(var i = 0; i < files.length; i++) {              (function(i) {                 var imgFilePath = SYNCDIR + '/' + files[i];                 fs.stat(imgFilePath, function(stat){                     if (stat.isFile()){                         filesOnly[i] = stat;                     }                 });             })(i);          }     } }); 
like image 180
Gary Chambers Avatar answered Sep 19 '22 18:09

Gary Chambers