简体   繁体   中英

Node.js loop printing in wrong order

I am trying to show some data from a couple of files in a directory, however there contents are printing out in the wrong order.

fs.readdir('files/sets', function(err, files){  
    for(var i = 0; i < files.length; i++){  
        console.log("_______________________________");
        readFile(files[i]);
    }
});

function readFile(file){
    csv()
    .from.path('files/training_set/'+file, {delimiter: ','})
    .transform(function(row){
        console.log(row);
    });
}

each file contains two lines:

File One:

John:
Hey there!

File Two:

Mary:
Whats up!

I would expect the output to be something like

____________________
John
Hey there!
____________________
Mary
Whats up!

But I actually get

____________________
____________________
John
Mary
Hey there! 
Whats up!

I have been searching and think its something to do with asynchronous function and the loop being to fast. But I cant seem to fix the problem. I have tried the following method, but results are the same.

fs.readdir('files/sets', function(err, files){  
    for(var i = 0; i < files.length; i++){  
        (function(j){  
            console.log("_______________________________");
            readFile(files[j]);
        })(i)
    }
});

readFile is an async operation and you are trying to run it synchronously without waiting for the callback to finish:

var async = require('async'); // npm install async

fs.readdir('files/sets', function(err, files){
  async.eachSeries(files,readFile,function(err){
   // more async stuff ...
  });
});

function readFile(file,callback){
    console.log("_______________________________");
    csv()
    .from.path('files/training_set/'+file, {delimiter: ','})
    .transform(function(row){
        console.log(row);
    }).on('close',function() {
      callback();
    });
}

Also, you have to run it in series if you need to wait to the previous file to finish.

Yes, you are seeing the result of asynchronous processing. You don't want to write a line at a time, since you will generally get the output for the files interspersed. Instead, you only want to write the entire output for a file to the console in a single call to console.log.

I think this should work:

fs.readdir('files/sets', function(err, files){
    for (var i = 0; i < files.length; i++){
        readFile(files[i]);
    }
});

function readFile(file){
    var outStr = "_______________________________";
    csv()
    .from.path('files/training_set/'+file, {delimiter: ','})
    .transform(function(row){
        outStr += '\n' + row;
    })
    .on('end', function(){
        console.log(outStr);
    });
}

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