2016-10-09 30 views
0
for (var i = 0; i < files.length; i++) { 
    fs.readFile(files[i], function(file, error, data) { 
     console.log("Successfully read a file", file) 
    }.bind(null, files[i])); 
} 

我想用Node.js來讀取某個目錄下的所有文件。 在回調循環中,由於javascript關閉,文件[i]不存在。 所以我將它綁定,但它作爲第一個參數出現。 我不知道如何使它作爲最後一個參數,謝謝。如何在javascript函數中綁定更多參數

+0

爲什麼不使用一個IIFE關閉變量? – adeneo

+0

'我不知道如何使它成爲最後一個參數,謝謝' - 簡單,你不能 –

+1

爲什麼在該代碼中不能定義'files [i]'? – adeneo

回答

1

這是一個有趣的問題,因爲它的東西很多JavaScript程序員的使用一個錯誤。 @torazaburo甚至說,爲什麼不刪除無意義的綁定,以及fs.readFile是異步的,這並非毫無意義。

我在下面創建了一個小片段來展示不同的想法,可能會有更多。

1st不做任何事情,不綁定,是@torazaburo提到失敗的唯一選擇。

第二個測試,就像OP的綁定到第一個參數的地方。

第三測試結合的「本」,可能還有它一定會成爲窗口對象,否則.. :)

4字試驗,使用功能關閉。

第五個測試,使用'let',因爲這將捕獲本地範圍而不僅僅是功能範圍。當然,這需要ES6,巴貝爾等

6測試,使用一種代理功能的改變參數的順序,這是我能想到的OP的closesest選項..

var files = ['file1','file2','file3']; 
 

 
function readFile(fn, callback) { 
 
    setTimeout(function() { 
 
    callback(null, 'filedata for ' + fn); 
 
    },1); 
 
} 
 

 
//test 1 do nothing 
 
function test1() { 
 
    console.log('test1, dont use bind'); 
 
    for (var i = 0; i < files.length; i++) { 
 
    readFile(files[i], function(file, error, data) { 
 
     console.log("Successfully read a file " + files[i]) 
 
    }); 
 
    } 
 
} 
 

 
//test 2 bind the first parameter 
 
function test2() { 
 
    console.log('test2, bind the first paramenter'); 
 
    for (var i = 0; i < files.length; i++) { 
 
    readFile(files[i], function(file, error, data) { 
 
     console.log("Successfully read a file " + file) 
 
    }.bind(null, files[i])); 
 
    } 
 
} 
 

 
//bind 'this', it only going to be the window object anyway, so why not use it 
 
function test3() { 
 
    console.log('test3, bind the this'); 
 
    for (var i = 0; i < files.length; i++) { 
 
    readFile(files[i], function(error, data) { 
 
     console.log("Successfully read a file " + this) 
 
    }.bind(files[i])); 
 
    } 
 
} 
 

 
//use a function closure, luckly forEach is going to do that for us 
 
function test4() { 
 
    console.log('test4, use a closure'); 
 
    files.forEach(function (file) { 
 
    readFile(file, function(error, data) { 
 
     console.log("Successfully read a file " + file) 
 
    }); 
 
    }); 
 
} 
 

 
//use let 
 
function test5() { 
 
    console.log('test5, use let instead of var'); 
 
    for (let i = 0; i < files.length; i++) { 
 
    readFile(files[i], function(error, data) { 
 
     console.log("Successfully read a file " + files[i]) 
 
    }); 
 
    } 
 
} 
 

 
//create proxy function 
 
function proxy_readFile(fn, cb) { 
 
    return readFile(fn, function (error, data) { 
 
    cb(error, data, fn) }); 
 
} 
 

 
function test6() { 
 
    console.log('test6, use a proxy function'); 
 
    for (var i = 0; i < files.length; i++) { 
 
    proxy_readFile(files[i], function(error, data, file) { 
 
     console.log("Successfully read a file " + file) 
 
    }); 
 
    } 
 
} 
 

 

 

 
setTimeout(test1,100); 
 
setTimeout(test2,200); 
 
setTimeout(test3,300); 
 
setTimeout(test4,400); 
 
setTimeout(test5,500); 
 
setTimeout(test6,600);

-1

使用包裝iife作爲封閉:

for (var i = 0; i < files.length; i++) { 
    fs.readFile(files[i], (function(file) { 
     return function(err, data){ 
     onFileRead(file, error, data); 
     } 
    })(files[i])); 
} 
function onFileRead(file, error, data){ 
    console.log("Successfully read a file", file) 
} 
+1

我不認爲這裏需要關閉。'files [i]'只是一個參數傳遞到'fs.readFile'函數,它在'for'循環的每一回閤中被同步地調用一次。 – Redu

+0

@Redu:它被用在回調函數中。GudzDaniel:你使用的是我們有'let'之前使用的解決方案,變量。 –