Поиск…


Вступление

При использовании асинхронного обратного вызова нам необходимо рассмотреть область действия. Особенно если внутри петли. Эта простая статья показывает, что не делать и простой рабочий пример.

Ошибочный код, можете ли вы понять, почему это использование ключа приведет к ошибкам?

var pipeline = {};
// (...) adding things in pipeline

for(var key in pipeline) {
  fs.stat(pipeline[key].path, function(err, stats) {
    if (err) {
      // clear that one
      delete pipeline[key];
      return;
    }
    // (...)
    pipeline[key].count++;
  });
} 

Проблема в том, что существует только один экземпляр ключа var . Все обратные вызовы будут иметь один и тот же ключевой экземпляр. В момент срабатывания обратного вызова ключ, скорее всего, будет увеличен и не будет указывать на элемент, для которого мы получаем статистику.

Правильное письмо

var pipeline = {};
// (...) adding things in pipeline

var processOneFile = function(key) {    
  fs.stat(pipeline[key].path, function(err, stats) {
    if (err) {
      // clear that one
      delete pipeline[key];
      return;
    }
    // (...)
    pipeline[key].count++;
  });
};
    
// verify it is not growing
for(var key in pipeline) {
  processOneFileInPipeline(key);
}

Создавая новую функцию, мы просматриваем ключ внутри функции, поэтому все обратные вызовы имеют свой собственный экземпляр ключа.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow