jquery: что происходит, когда вы передаете отложенный объект в «then»? - PullRequest
3 голосов
/ 30 сентября 2011

Я уже некоторое время исследую отложенные объекты jquery, и я нахожусь в тупике.

Методы "done", всегда "then", "etc" принимают в качестве аргументов свои аргументы,функции, которые должны вызываться при разрешении отложенного объекта.

Однако я попытался объединить запросы, передав отложенный объект в метод Always, и что , похоже, тоже работает:

// A is an array of data
var req = ajax(url + "?d=" + A[0]).done(processResults).fail(reportFailure);
for (var i = 1 ; i < A.length ; i++) {
  var tmp = ajax(url + "?d=" + A[i]).done(processResults).fail(reportFailure);
  req.always(tmp);
  req = tmp;
}

Однако на самом деле это не работает.Потому что, когда я следую приведенному выше коду с таким:

req.always(foobar);

, кажется, что foobar вызывается в какое-то случайное время, не обязательно после обработки последнего элемента в массиве.

Будет ли этолучше использовать когда?

// A is an array of data
var req = $.when(ajax(url + "?d=" + A[0]).done(processResults).fail(reportFailure));
for (var i = 1 ; i < A.length ; i++) {
  req = $.when(req, ajax(url + "?d=" + A[i]).done(processResults).fail(reportFailure));
}
req.always(foobar);

Приведет ли приведенный выше код (с использованием «когда») к тому, что запросы ajax будут выполняться один за другим, или они будут выполняться одновременно?

Я изучилМежду прочим, цепочка с "pipe", но из-за проблем с областью видимости, я думаю, было бы сложнее использовать "pipe" с циклом for, как описано выше.

Кроме того, почему оригинальный код "почти работает"?Что там происходит?Выполняет ли он отложенный объект, как если бы он был функцией, и что происходит, когда он это делает?

1 Ответ

2 голосов
/ 30 сентября 2011

Вы должны создать массив и использовать javascript apply :

//create an array of one deferred per element
var requests =  $.map(A, function(index, a){return= $.ajax(url + "?d=" + a);});
//merge all deferreds into a single one
var mergedRequest = $.when.apply(null, requests);

mergedRequest.done(function(res0, res1, ...){
   //your code goes here
   //if you want results as an array just use arguments
   arguments.length == A.length;
});

РЕДАКТИРОВАТЬ: Если вы хотите, чтобы ваши вызовы выполнялись последовательно, выполните:

...