2014-03-27 20 views
2

我试图从目录中的几个文件中显示一些数据,但是其中的内容以错误的顺序打印出来。Node.js以错误的顺序循环打印

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

每个文件都包含两行:

文件中的一个:

John: 
Hey there! 

文件中的两个:

Mary: 
Whats up! 

我期望的输出是这样的

____________________ 
John 
Hey there! 
____________________ 
Mary 
Whats up! 

但我真正得到

____________________ 
____________________ 
John 
Mary 
Hey there! 
Whats up! 

我一直在寻找,并认为它是与异步函数和循环是快速。但我似乎无法解决这个问题。我尝试了以下方法,但结果相同。

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

看起来更像是你希望节点按给定的顺序读取文件,而不是? – adeneo

+0

正确,我期待它打印该行,读取一个文件,打印另一行,然后读取下一个文件。 – wazzaday

+0

嗯,是的,但是按照什么顺序读取文件,您如何知道readdir按照您期望的顺序读取目录中的文件。在迭代之前对文件数组进行排序以解决此问题,但是您必须通过文件名告诉我们您期望的顺序? – adeneo

回答

1

readFile是一个异步操作和你想无需等待回调结束同步运行:

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

而且,你必须如果您需要等待上一个文件完成,请按顺序运行它。

+0

谢谢!我曾研究过这个模块,但并未使用eachSeries。回调的目的是什么?纯粹是因为错误吗? – wazzaday

+0

在异步操作中,无论如何,总是需要回调。这是一种说“我们已经完成了这个块的运行”的方式。如果你不叫它,它会永远挂在那里。在这个例子中,'callback'是具有“// more async stuff”注释的函数 – Maroshii

+0

谢谢,我刚刚在这里阅读了一些内容https://github.com/caolan/async#eachSeries - 谢谢你的帮助 :) – wazzaday

0

是的,你正在看到异步处理的结果。你不想一次写一行,因为你通常会得到散布文件的输出。相反,您只需要将一个文件的整个输出写入控制台,只需一次调用console.log即可。

我认为这应该工作:

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