Подтвердить что ты не робот

Лучший способ передать переменные в функции обратного вызова в 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.

Спасибо.

4b9b3361

Ответ 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...");
            });
        });
    });
}