如何在javascript函数中绑定更多参数

时间:2016-10-09 11:22:33

标签: javascript node.js

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]不存在。 所以我绑定它但它看起来是第一个参数。 我想知道如何将它作为最后一个参数,谢谢。

2 个答案:

答案 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)
}