2014-03-27 46 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); 
    }); 
}