Область действия и асинхронный JavaScript - PullRequest
6 голосов
/ 03 августа 2010

Недавно я столкнулся с проблемой на работе, в которой, по крайней мере, исходя из моих знаний JavaScript, я получил невозможный результат.Я надеюсь, что кто-то может объяснить, что здесь происходит и почему фактические результаты отличаются от моих ожидаемых результатов.

Ожидаемые результаты в консоли

id: a , x: 1
id: b , x: 1
id: c , x: 1

Фактические результаты в консоли

id: c , x: 1
id: c , x: 2
id: c , x: 3

Код

function MyClass(id)
{
    var x = 0;

    return function()
    {
        return function()
        {
            x += 1;
            console.log("id: ", id, ", x: ", x);
        }
    }
}


function DoStuff(id)
{
    var q = MyClass(id);
    response_callback = q();
    setTimeout(function(){ response_callback(); }, 50);
}

DoStuff("a");
DoStuff("b");
DoStuff("c");

1 Ответ

6 голосов
/ 03 августа 2010
response_callback = q();

Это.Вы не объявляли response_callback в любой области, поэтому она неявно входит в глобальную область ...

Это означает, что вы перезаписываете ее каждый раз, когда вызываете DoStuff().Вы думаете , что вы получаете три разные функции, захваченные и вызванные, но есть только одна ...

 var response_callback = q(); // should set you back on track

Конечно, то, как вы сейчас это структурировали, немного напрасно MyClass способность возвращать функцию, которая возвращает функцию.Вы могли бы написать:

function DoStuff(id)
{
  var q = MyClass(id);
  // ... do other strange and horrible things with q ...
  setTimeout(q(), 50);
}

... и увидеть те же результаты без ненужного закрытия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...