JQuery цепочка с процессом и трубой не работает для меня
Трубопроводы и цепи для меня в новинку...
1
2
У меня возникли проблемы с запуском этого маленького сценария. У меня есть массив URL-адресов, которые мне нужно синхронно запускать с AJAX. Мне нужно дождаться успешного ответа от каждого url-адреса (некоторые могут иметь задержку, так как они будут выполнять большие SQL-запросы и создавать отчеты), прежде чем переходить к следующей итерации. Если он не добьется успеха, то весь процесс должен прекратиться.
Я думаю, что я близок после много возни, но вы увидите, что это не работает правильно. Может быть, один из вас, гуру, поможет мне в этом?
//counter
var i = 0;
//array of local urls that I need to trigger one after another
var arrValues = [
"http://fiddle.jshell.net/",
"http://fiddle.jshell.net/",
"http://fiddle.jshell.net/"];
//the step i need to repeat until done
var step = (function () {
//expect to see this alert called for each iteration (only happens once?)
alert(arrValues[i]+i);
var url = arrValues[i];
var model = {};
model.process = function () {
log('Starting: ' + url + i);
return $.ajax(url)
.done(function (jqXHR, textStatus, errorThrown) {
log(textStatus + ' ' + url + i + ' Done');
})
.fail(function (jqXHR, textStatus, errorThrown) {
log(textStatus + ' Failed');
});
};
return model;
}());
//just outputting to the div here
function log(message) {
$("#output").append($("<div></div>").text(message));
}
//start the process
log("Starting To Build Report");
//iterate through the array
$.each(arrValues, function (intIndex, objValue) {
// I need to wait for success before starting the next step or fail and throw
// the errors below - you will see this does not work now and never gets to the
// .done or .fail or .always
step.process().pipe( function () {
i++;
step.process();
});
}).done(function () {
log("The process completed successfully");
})
.fail(function () {
log("One of the steps failed");
})
.always(function () {
log("End of process");
});
1 ответ:
Вы почти на месте, но детали очень важны. Сноровка такова:
- модифицировать
step
быть функцией (не объектом), которая возвращает функцию, которая сама возвращает наблюдаемый объект (т. е. обещание jqXHR)- , чтобы разрешить
step
принимать инкрементное целое числоi
в качестве параметра; это позволяет избежать необходимости поддерживать выполнениеi
во внешней области- построить цепочку
.then()
, в которой каждыйthen()
принимает в качестве аргумента функцию, возвращаемуюstep()
- чтобы посеять цепочку
.then()
с решительным обещанием начать ее- прикрепить окончательный текст
.done()
,.fail()
,.always()
до конца цепочкиthen()
.Примечание: из jQuery 1.8,
.pipe()
устарел в пользу пересмотренного.then()
.Вот код :
var arrValues = [ "http://fiddle.jshell.net/", "http://fiddle.jshell.net/", "http://fiddle.jshell.net/" ]; function step(i) { return function() { var url = arrValues[i]; log('Starting: ' + url + i); return $.ajax(url).done(function(data, textStatus, jqXHR) { log(textStatus + ' ' + url + i + ' Done'); }).fail(function(jqXHR, textStatus, errorThrown) { log(textStatus + ' ' + url + i + ' Failed'); }); } }; function log(message) { $("#output").append($("<div/>").text(message)); } log("Starting To Build Report"); var p = $.Deferred().resolve().promise(); $.each(arrValues, function(i, url) { p = p.then(step(i)); }); p.done(function() { log("The process completed successfully"); }).fail(function() { log("One of the steps failed"); }).always(function() { log("End of process"); });
Обновленная скрипка