13

我一直在想,除了使用bind().

这是一个例子:

var fs = require('fs');

for(var i = 0; i < 100; i++) {
    fs.writeFile(i + ".txt", i, function(error) {
        fs.stat(this.i + ".txt", function() {
            fs.rename(this.i + ".txt", this.i + ".new.txt", function() {
               console.log("[" + this.i + "] Done...");
            }.bind({ i: this.i }));
        }.bind({ i: this.i }));
    }.bind({ i: i }));
}

注意bind()所有方法,只需传递i.

谢谢。

4

4 回答 4

15

JavaScript 中的变量对整个函数范围都有效。这意味着您可以定义一个变量x(( var x = ...) 并且它仍然可以在所有函数中访问,您在同一个调用范围内定义。(有关详细信息,您可能需要查看JavaScript 闭包

您的案例的问题是,您ifor loop. 如果只是访问i回调函数中的 ,您将收到第一个不再在循环中的值。

i您可以通过使用as 参数调用新函数来避免这种情况,如下所示:

var fs = require('fs');

// still use your for-loop for the initial index
// but rename i to index to avoid confusion
for (var index = 0; index < 100; index++) {
  // now build a function for the scoping
  (function(i) {
    // inside this function the i will not be modified
    // as it is passed as an argument
    fs.writeFile(i + ".txt", i, function(error) {
      fs.stat(i + ".txt", function() {
        fs.rename(i + ".txt", i + ".new.txt", function() {
          console.log("[" + i + "] Done...");
        });
      });
    });
  })(index) // call it with index, that will be i inside the function
}
于 2012-09-28T06:36:31.403 回答
7

我想在下面做:

var fs = require('fs');

var getWriteFileCallback = function(index) {
  return function(error) {                           
    fs.stat(index + '.txt', function() {             
      fs.rename(index + '.txt', index + '.new.txt', function() {
        console.log("[" + index + "] Done...");      
      });                                            
    });                                              
  };                                                 
}                                                    

for(var i = 0; i < 100; i++) {
  fs.writeFile(i + ".txt", i, getWriteFileCallback(i));
}
于 2012-09-28T06:45:31.577 回答
0

您可以在 for 循环中使用 let 而不是 var。这是(至少在我看来)两者最大的区别!只要确保您使用严格模式,否则让不会为您工作。

var fs = require('fs');

for(let i = 0; i < 100; i++) {
    fs.writeFile(i + ".txt", i, function(error) {
        fs.stat(i + ".txt", function() {
            fs.rename(i + ".txt", i + ".new.txt", function() {
               console.log("[" + i + "] Done...");
            });
        });
    });
}
于 2016-03-12T11:23:47.040 回答
0

我通常这样做的方式是.bind({vars here})在回调中使用 this.varname 然后引用它。确保不要在回调中使用箭头函数,而只是一个普通函数。

someArray = [{id:1}, {id:4}, {id:10}]

someArray.forEach(item=>{ 
    // item.id will be correct here
    someAsyncFunc({id:item.id}, function(err, data){
        // we need to use this.tempItem.id here because it could be returned sometime in the future
        console.log(`someAsyncFunc on item.id ${this.tempItem.id} returned`)
    }.bind({tempItem:item}))
})
于 2018-03-19T18:02:07.507 回答