javascript 在 Node.js 中将变量传递给回调函数的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12634647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to pass variables into callback functions in Node.js
提问by Justin
I've been wondering, is there a better way to pass variables into callback functions in node.js other than using bind()
.
我一直在想,除了使用bind()
.
Here is an example:
下面是一个例子:
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 }));
}
Notice the bind()
methods all the way up, simply passing the value of i
.
注意bind()
一路向上的方法,只需传递i
.
Thanks.
谢谢。
回答by Tharabas
Variables in JavaScript are valid for the whole function scope.
This means that you can define a variable x
((var x = ...
) and it is still accessible in all functions, you define within the same calling scope.
(For detailed information you might want to take a look at JavaScript Closures
JavaScript 中的变量对整个函数作用域都有效。这意味着您可以定义一个变量x
(( var x = ...
) 并且它仍然可以在所有函数中访问,您定义在同一个调用范围内。(有关详细信息,您可能需要查看JavaScript Closures
The problem of your case is, that you manipulate your i
during the for loop
.
If simply access the i
in the callback functions, you'd recieve the first value that is no longer in the loop.
您的案例的问题是,您i
在for loop
. 如果只是访问i
回调函数中的 ,您将收到不再在循环中的第一个值。
You can avoid that by calling a new function with the i
as argument, like this:
您可以通过使用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
}
回答by xdazz
I would like to do with below:
我想在下面做:
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));
}
回答by Gonen
You can use let instead of var in your for loop. This is (in my eyes at least) the biggest difference between the two! Just make sure you use strict mode or let won't work for you.
您可以在 for 循环中使用 let 而不是 var 。这是(至少在我看来)两者之间最大的区别!只要确保您使用严格模式或 let 对您不起作用。
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...");
});
});
});
}
回答by Jim Factor
The way I usually do it is to use .bind({vars here})
and then reference it with this.varname inside of the callback. Make sure not to use arrow function on your callback, just a plain function.
我通常这样做的方法是使用.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}))
})