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

Jus*_*tin 13 javascript callback node.js

我一直在想,有没有更好的方法将变量传递给node.js中的回调函数而不是使用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 }));
}
Run Code Online (Sandbox Code Playgroud)

注意bind()方法一直向上,只需传递值i.

谢谢.

Tha*_*bas 15

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

你的情况的问题是,你i在期间操纵你for loop.如果只是访问i回调函数,你就会收到循环中不再存在的第一个值.

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

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
}
Run Code Online (Sandbox Code Playgroud)

  • 不必要的匿名函数会使脚本变慢 (2认同)

xda*_*azz 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));
}
Run Code Online (Sandbox Code Playgroud)