У меня есть несколько запросов ajax, запущенных одновременно, и я хочу, чтобы они подождали, пока последний будет возвращен, а затем запустите обработчик успеха во всех вызовах ajax. Для упрощенного примера рассмотрим:
$.ajax({//ajax call 1
url:page1.php,
success: function(data1){
//do something with data1
}
});
....
$.ajax({//ajax call 2
url:page2.php,
success: function(data2){
//do something with data2
}
});
//consider more than just two concurrent requests
Скажем, что все запросы отправляются одновременно. Поскольку они асинхронны, они возвращаются в разное время. Скажем, один запрос принимает 100 мс для возврата, а другой запрос занимает 3000 мс для возврата. Я, очевидно, не знаю, какой из них будет возвращен первым или последним. Все они каким-то образом обновляют DOM, и я хочу, чтобы эти изменения отображались в средстве просмотра одновременно за одно обновление. Как это сделать?
Самое лучшее, о чем я могу думать, - сохранить данные1 и data2 в качестве глобальных переменных. А затем есть переменная счетчика, которая учитывает каждый раз, когда возвращается успех. Затем, на счетчике == TOTAL_NUM_REQUESTS вызывается функция типа updateAll(), затем проходит через все глобальные переменные и помещает их туда, куда им нужно идти. Но это кажется грязным и подверженным ошибкам. Плюс к этому было бы много глобальных переменных.
В идеале я хочу, чтобы обработчики успеха спали по возвращении, а затем при моем состоянии подсчета всех из них, как они были возвращены, отправляйте сообщения о пробуждении всем им, и они могут возобновить выполнение. Это кажется самым чистым, но я не знаю о такой функциональности, как это в javascriptland.
Есть ли у кого-нибудь интересные идеи для этого?
ANSWER UPDATE
Спасибо Ли ниже, я смог получить решение. Мое решение было похоже на его ниже. Я создаю список переменных async
, которые были назначены вызову $.ajax. Изначально обработчик успеха этих вызовов ajax все еще вызывался, поэтому я удалил их и поместил их в другую функцию, которую впоследствии должен был вызвать этот блок when
, который я написал. Я передал results
в функцию, подобную этой:
var results = [];
results.push(async1);
results.push(async2);
... for all the results ...
$.when.apply(this, results).done(function() {
for(var i=0;i<arguments.length;i++){
dataobject=arguments[i][0]
if(dataobject.variousattribute)
mySuccessHandlerFirstGuy(dataobject)
else if(dataobject.anotherattribute)
mySuccessHandlerSecondGuy(dataobject)
//etc ....
}
};
Объект arguments занял немного работы, чтобы выяснить, что это было. Это был массив 2d (список списков). Первый индекс представлял возвращаемый объект, соответствующий заданному запросу ajax. Кажется, что все в порядке, но было бы лучше, если бы ваш сервер вернул то, что вы можете искать, и напишите блок if/else соответственно. Затем в этом элементе в этом списке есть 3 элемента. Первый - это значение, которое было возвращено с сервера, то есть то, что вы хотите. Вторая всегда была строкой success
, которую вы, вероятно, можете использовать, чтобы проверить, работал ли вызов. И третий элемент в этом списке, по-видимому, является первоначальным запросом (хотя я не уверен). Это было бесполезно для меня.
В любом случае, я надеюсь, что это поможет кому-то в будущем. И еще раз спасибо Ли, чтобы указать мне в правильном направлении.