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关闭,files [i]不存在。
所以我绑定它但它看起来是第一个参数。
我想知道如何将它作为最后一个参数,谢谢。
答案 0 :(得分:1)
这是一个有趣的问题,因为很多javascript程序员都犯了错误。 @torazaburo甚至说为什么不删除无意义的绑定,这不是没有意义的,因为fs.readFile是异步的。
我在下面创建了一个小片段来展示不同的想法,可能会有更多。
1st是什么也不做,不绑定,是@torazaburo提到失败的唯一选择。
第二次测试,就像他已经绑定到第一个参数的OP一样。
第3次测试绑定'this',可能以及它只会是window对象,否则.. :)
第4次测试,使用函数闭包。
第5次测试,使用'let',因为这将捕获本地范围而不仅仅是功能范围。这当然需要es6,babel等。
第6次测试,使用一种代理函数来改变参数的顺序,这是我能为OP考虑的最接近的选项..
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 :(得分:-1)
使用wrapper 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)
}