2012-06-20 49 views
4

我需要逐行讀取文件,並相應地更改一個變量。 我通常會用PHP寫這個...但我決定接受挑戰。Node和Lazy:我如何知道它何時完成?

我寫道:

fs = require('fs'); 
Lazy = require('lazy'); 
path = require('path'); 

files = fs.readdirSync('.'); 
var software = {}; 


files.forEach(function(fileName){ 


    var m; 
    if(m = fileName.match(/^(.*)\.txt$/)){ 
    name = m[1]; 

    console.log("Processing file: " + fileName); 
    software[name] = {}; 
    console.log("Software 1: %j",software); 

    var section = 'unset'; 
    new Lazy(fs.createReadStream(fileName)).lines.forEach(
     function(line){ 
     var m; 
     line = line + ''; 
     if(m = line.match(/^([a-zA-Z_]*):$/)){ 
      section = m[1]; 
      software[name][section] = ''; 
      console.log("Switching to section " + m[1]); 
      console.log("Software 2: %j",software); 
     } else if (line == '.'){ 
      section = 'unset' 
     } else if (line == ''){ 
      section = 'unset' 
     } else { 
      console.log("LINE: " + line) ; 
      software[name][section] = software[name][section] + line + "\n"; 
      console.log("Software 3: %j",software); 
     } 
     } 

    ); 
    } 

}); 

console.log("Software 4: %j",software); 
從代碼

除了是很醜陋,很未優化,我有麻煩當最後一行打印,「軟件」變量尚未填充!我猜懶惰是異步的。所以,它基本上是有效的,但是「在稍後的某個時刻」。這很好,但是......當那個重要的循環填充軟件變量時,我在哪裏編寫代碼實際上完成了?!?

根據要求:數據玩!

只需創建 「something.txt」,並寫:

name: 
Name 1 
. 

Option 1: 
Value 1 
. 

Option 2: 
Value 2 
. 

Option 3: 
Multi 
Line 
Value 
. 

Another_section: 
Again 
. 

芝加哥商業交易所。

+0

好問題!你能給我一些簡單的示例數據來玩嗎? – jsalonen

+0

我的意思是,我*可以*存儲fs.createReadStream(fileName)).lines.length併爲每一行增加一個計數器,然後當行數達到時調用一個函數......但這似乎完全是瘋了。一定! – Merc

回答

15

由庫返回的懶惰的實例是EventEmitters,它發射EN事件稱爲pipe操作時,「設置」齊全:

new Lazy(
    ... 
).on('pipe', function() { 
    // all done 
}); 

修改代碼以使用本次活動結果(唯一的變化是接近底部):

fs = require('fs'); 
Lazy = require('lazy'); 
path = require('path'); 

files = fs.readdirSync('.'); 
var software = {}; 


files.forEach(function(fileName){ 


    var m; 
    if(m = fileName.match(/^(.*)\.txt$/)){ 
    name = m[1]; 

    console.log("Processing file: " + fileName); 
    software[name] = {}; 
    console.log("Software 1: %j",software); 

    var section = 'unset'; 
    new Lazy(fs.createReadStream(fileName)).lines.forEach(
     function(line){ 
     var m; 
     line = line + ''; 
     if(m = line.match(/^([a-zA-Z_]*):$/)){ 
      section = m[1]; 
      software[name][section] = ''; 
      console.log("Switching to section " + m[1]); 
      console.log("Software 2: %j",software); 
     } else if (line == '.'){ 
      section = 'unset' 
     } else if (line == ''){ 
      section = 'unset' 
     } else { 
      console.log("LINE: " + line) ; 
      software[name][section] = software[name][section] + line + "\n"; 
      console.log("Software 3: %j",software); 
     } 
     } 

    ).on('pipe', function() { 
     console.log("Software 4: %j",software); 
    }); 
    } 

}); 

[編輯]要回答你關於我是怎麼發現這個信息的問題:

我確實檢查出the source file for the project;我知道圖書館有一個sum方法可以鏈接到懶惰的例子來總結一切的最後; code for that method調用foldr,並且code for that method監聽名爲pipeName的事件,該事件默認爲in line 22pipe

+0

我想問問......你是怎麼知道的?!?我讀了Lasy的文檔,並沒有從那裏弄清楚。就「管道」或「事件」或「發射」而言,這裏沒有太多......我的意思是,你是如何發現這一點的?您是否需要深入瞭解源代碼? – Merc

+1

是的,我同意文檔不是很全面;我非常喜歡'async'作爲我選擇的流控制庫。我已經更新了一些附加信息的答案。 –

+0

Btw。謝謝你的提示。 'async'看起來真好! – jsalonen

相關問題