将变量传递给Node.js中的回调函数的最佳方法

时间:2012-09-28 06:23:24

标签: javascript node.js callback

我一直在想,除了使用bind()之外,是否有更好的方法将变量传递给node.js中的回调函数。

以下是一个例子:

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 个答案:

答案 0 :(得分:15)

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

您的案例的问题是,您在i期间操纵了for loop。 如果只是访问回调函数中的i,您就会收到不再在循环中的第一个值

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

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
}

答案 1 :(得分: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));
}

答案 2 :(得分: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...");
            });
        });
    });
}

答案 3 :(得分: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}))
})