Лучший способ передать переменные в функции обратного вызова в 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 }));
}
Обратите внимание на методы bind()
полностью, просто передав значение i
.
Спасибо.
Ответы
Ответ 1
Переменные в JavaScript действительны для всей области функций.
Это означает, что вы можете определить переменную x
((var x = ...
)), и она по-прежнему доступна во всех функциях, которые вы определяете в пределах одной и той же области вызова.
(Для получения подробной информации вы можете взглянуть на Закрытие JavaScript
Проблема вашего дела в том, что вы управляете своим 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
}
Ответ 2
Я хотел бы сделать следующее:
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));
}
Ответ 3
Вы можете использовать let вместо var в вашем цикле for. Это (по крайней мере, в моих глазах) самая большая разница между ними!
Просто убедитесь, что вы используете строгий режим или не будете работать для вас.
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...");
});
});
});
}