Отправка одного запроса AJAX за раз из цикла
Я знаю, что этот вопрос задавали бесчисленное количество раз, но я не могу понять, насколько я могу заставить этот ответ работать в моем случае: ждать возвращения функции async javascript
Я зацикливаюсь на некоторых "телевизионных каналах" во внешнем круге, а затем зацикливаюсь на датах в неделю во внутреннем канале. Во внутреннем цикле я делаю запрос ajax на сервер для извлечения данных, и затем я сохраняю/кеширую его для последующего использования так
var dates = []; //<-- Contains a list of dates for the coming week
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];
for(ch = 0; ch < storedChannels.length; ch++) {
var channel = storedChannels[ch];
for(d=0; d < 7; d++) {
var currentDate = dates[d];
ajax({
url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
complete: function(res) {
CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
},
});
//Want to wait here till the ajax request completes.
//Do not want to continue to next iteration.
//Do not want to fire of 50 bazillion ajax requests all at once
//Why? Very limited bandwidth scenario, plenty of channels
}
}
PS: НЕТ JQuery, пожалуйста! Только простые решения JS
Большое спасибо!
Ответы
Ответ 1
Вы хотите что-то вроде этого. Я не тестировал его, но, надеюсь, вы должны получить эту идею.
var dates = []; //<-- Contains a list of dates for the coming week
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];
function ProcessNext(ch, d) {
if (d < 7) {
d++;
} else {
d=0;
if (ch < storedChannels.length) {
ch++;
} else {
return;
}
}
var channel = storedChannels[ch];
var currentDate = dates[d];
ajax({
url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
complete: function(res) {
CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
ProcessNext(ch, d);
},
});
}
ProcessNext(0, 0);
Ответ 2
Вам нужно превратить ваш цикл в цепочку обратных вызовов.
Вместо использования цикла вы должны сделать свой обратный вызов своей исходной функцией, но с более высоким значением параметра.
Ответ 3
То, что вы пытаетесь сделать, объясняется в асинхронных шаблонах итераций руководством Педро Тейшейры. В примерах используется Node.js, но вы можете использовать те же шаблоны в браузере. В основном вам нужно преобразовать ваши циклы в последовательные обратные вызовы, ожидающие друг друга, чтобы завершить, поэтому следующий запрос AJAX уволен из обратного вызова успеха предыдущего и т.д. Это можно сделать, не блокируя браузер, но не в циклах. См. Этот учебник.
Ответ 4
По сути, ответ заключается в использовании рекурсивных вызовов вместо использования циклов. Просто хотел добавить этот ответ для тех, кому может быть интересно "для петлевых гнезд" глубже, чем 2 уровня. Как вы можете видеть, его легко распространить на столько "гнезд", сколько вам нравится.
Оригинальный кредит распространяется на VatooVatoo в Java на форумах DaniWeb.
Вот код, протестирован и работает (без битов ajax, конечно, но вы можете добавить это сами):
<html>
<head>
<script type="text/javascript">
function loopRecurse(a, b, c)
{
if(c >= 2) {
b++;
c=0;
loopRecurse(a, b, c);
return;
}
if(b >= 2) {
a++;
b=0;
loopRecurse(a, b, c);
return;
}
if(a >= 2) return;
document.write("<div>" + a + "|" + b + "|" + c + "</div>");
c++;
loopRecurse(a, b, c);
}
loopRecurse(0, 0, 0);
</script>
</head>
<body>
<!-- output
0|0|0
0|0|1
0|1|0
0|1|1
1|0|0
1|0|1
1|1|0
1|1|1
-->
</body>
</html>
Ответ 5
См. документацию XMLHttpRequest (связанная с MDC, но не имеет значения). В основном условие, которое вы ищете, request.readyState==4
- предполагается, что ваш ajax()
возвращает фактический объект XMLHttpRequest
.