2016-10-09 28 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'之前使用的解决方案,变量。 –