Асинхронность внутри цикла - PullRequest
5 голосов
/ 19 марта 2011

Я использую API jQuery $.getJSON() для извлечения данных из заданного URL-адреса для набора утилит. Мне бы очень хотелось найти способ повторного использования кода (он абсолютно одинаковый) для каждой утилиты. Поскольку цикл выполняется без учета вызова ajax, я не смог найти способ сохранить значение цикла.

Это описание отстой, я знаю, так что здесь фрагмент кода, который определяет его немного лучше:

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

/** Retrieve known utility providers for the given zip code */
for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, function( data, status ) {
    alert( 'Processing ' + type );
  });
}

Мне нужно найти способ передать значение типа в обратный вызов, чтобы я мог применить правильный синтаксис. Без этого все 3 цикла выполняются против утилиты «Вода». Я знаю, почему он не работает, мне просто интересно, есть ли разумный обходной путь.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 19 марта 2011

Создать замыкание

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

function getCallBack(type){
   return function(data,status){
     alert( 'Processing ' + type );
   }
}

/** Retrieve known utility providers for the given zip code */

for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, getCallBack(type));
}
3 голосов
/ 19 марта 2011

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

Это анонимное закрытие имеет собственную область видимости, которая содержит свои собственные переменные (включая переданный параметр), которые могут переопределять переменные внешнего цикла, например ::

..., success: (function(type) {
    return function() {
        alert(type);
    }
}(type))

type в скобках снаружи - это переменная цикла. type в объявлении функции - это параметр , который входит в область нового замыкания. Когда вызывается alert, он использует тот, который ближе всего по объему, то есть параметр.

Конечно, параметр может иметь свое собственное имя переменной, оно не обязательно должно быть таким же, как во внешней области видимости! Если бы оно было другим, то оба были бы доступны, но версия с внешней областью действия всегда имела бы одно и то же значение.

0 голосов
/ 19 марта 2011

Вы можете присвоить значение 'type' переменной-члену для каждого ajax-запроса и проверить его с помощью ключевого слова this в функции успешного выполнения обратного вызова:

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

/** Retrieve known utility providers for the given zip code */
for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  var jsonReq = $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, function( data, status ) {
    alert( 'Processing ' + this.utilityType );
  });
  jsonReq.utilityType = type;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...