2016-10-23 2 views
1

У меня проблема с переменной областью в обратном вызове. Это немного сложно объяснить, поэтому вот упрощенный код, который я использую. Обратите внимание, что я использую ES6.Javascript: переменная область в обратном вызове?

class Foo { 
    constructor() { /* ... */ } 

    // Execute 'callback' after 'delay' has passed (works fine) 
    timer(delay, callback) { /* ... */ } 

    // Emit a sound of 'frequency' for 'duration' (works fine) 
    sound(duration, frequency) { /* ... */ } 

    // Play each 'frequency' for 'duration' 
    music(duration, frequencyArray) { 
     var that = this; 
     for (var i = 0; i < frequencyArray.length; i++) { 
      var freq = frequencyArray[i]; 
      this.timer(duration*i, function() { 
       // The line below doesn't work properly 
       // 'freq' is always equal to the last value of the array 
       that.sound(duration, freq); 
      }); 
     } 
    } 
} 

// Usage 
var F = new Foo(); 
F.music(200, [150, 200, 250]); 

В приведенном выше примере, вместо того, чтобы услышать 3 различных нот (150, 200, 250), я слышал, в 3 раза ту же ноту частоты 250.

Я понимаю, почему (var freq равно 250, когда обратный вызов на самом деле называется, но я не знаю, как исправить это. Любую идею?

Спасибо!

ответ

0

при использовании замедленного обратного вызова в цикле, вы должны создать специальную сферу для этого звонка. at, у вас есть 2 основных решения: создайте fonction в вашем классе или локальную анонимную функцию, например (function (localVar) {/ * Запустите ваш отложенный обратный вызов здесь, используя локальные переменные, переданные этой анонимной функции * /}) (localVar);

Это можно легко объяснить тем фактом, что обратный вызов использует область действия цикла, si для каждого цикла, значение переменной изменяется и когда вызывается обратный вызов, ваша переменная имеет последнее значение.

Смежные вопросы