Трубопроводы и цепочки для меня в новинку ...
У меня проблема с работой этого небольшого скрипта. У меня есть массив 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");
});
Похожие вопросы
Новые вопросы
jquery
jQuery — это библиотека JavaScript. Также рассмотрите возможность добавления тега JavaScript. jQuery — это популярная кросс-браузерная библиотека JavaScript, которая упрощает обход объектной модели документа (DOM), обработку событий, анимацию и взаимодействие AJAX, сводя к минимуму расхождения между браузерами. Вопрос с тегом jQuery должен быть связан с jQuery, поэтому jQuery должен использоваться рассматриваемым кодом, и в вопросе должны быть как минимум элементы, связанные с использованием jQuery.