2011-05-13 70 views
5

我在Node.js中構建了一個系統,該系統應該查找文件夾數組中的所有文件,統計它們,然後使用該信息做一些額外的工作。爲回調函數添加其他參數

我使用fs.readdir()從每個文件夾同步獲取所有文件。我的代碼如下所示:

for(i=0,max=paths.length; i<max; i++) { 
    var path = paths.pop(); 
    console.log("READING PATH: " + path); 
    fs.readdir(path, function(err, files) { handleDir(err, files, path); }); 
} 

的問題是,根據執行的速度有多快READDIR(),handleDir()越來越走錯了路。發生這種情況是因爲回調運行時,下一個循環已經開始 - 這意味着路徑變量已經改變。

所以,我需要做的是以某種方式鎖定該路徑變量爲它的特定回調函數。我想不出有什麼好辦法做到這一點 - 任何人都有一些想法?

回答

7

沒有塊範圍,因此使用範圍函數。

for(var i=0, path, max=paths.length; i<max; i++) { 
    path = paths.pop(); 
    console.log("READING PATH: " + path); 
    handlePath(path); 
} 
function handlePath (path) { 
    fs.readdir(path, onPathRead); 
    function onPathRead (err, files) { 
     handleDir(err, files, path); 
    } 
} 
6

這是JS對我來說比較煩人的部分之一。創建單獨函數的另一種方法(如@generalhenry所演示的)是將代碼封裝在路徑變量更改之前執行的匿名函數中。

for(i=0,max=paths.length; i<max; i++) { 
    var path = paths.pop(); 
    console.log("READING PATH: " + path); 
    fs.readdir(path, 
     (function(p){ 
      return function(err, files) { 
       handleDir(err, files, p); 
      }; 
     })(path); 
    ); 
} 

無論哪種方式,重要的一點是重新分配的路徑變量的值之前函數的上下文(匿名或不)啓動。

+0

我喜歡這個技術用於其簡潔 – nicolaskruchten 2011-05-14 14:43:09

1

這實際上是JavaScript的一個惱人的功能,以至於CoffeeScript的(這是編譯爲Java腳本語言)與它打交道,在do操作上for的特定方式。在CoffeeScript中原來的功能是:

for path in paths 
    fs.readdir path, (err, files) -> handleDir(err, files, path) 

和解決問題的方法是:

for path in paths 
    do (path) -> 
    fs.readdir path, (err, files) -> handleDir(err, files, path) 
+0

這是否只是編譯到同樣的事情上述兩個答案? – jwegner 2011-05-14 16:33:53

+0

或多或少,是的,我只是想插上這個(IMO)非常優雅和簡潔的解決方案:) – nicolaskruchten 2011-05-14 16:45:36

0

我一直在尋找同樣的事情,並與解決方案最終會在這裏它是一個簡單的例子如果有人想要通過這個。

var FA = function(data){ 
    console.log("IN A:"+data) 
    FC(data,"LastName"); 
}; 
var FC = function(data,d2){ 
    console.log("IN C:"+data,d2) 
}; 
var FB = function(data){ 
    console.log("IN B:"+data); 
    FA(data) 
}; 
FB('FirstName') 
相關問題