У меня есть стандартный объект javascript, прототип которого расширен с помощью метода .start()
, который принимает в качестве аргументов 2 обратных вызова: success
и failure
соответственно. Этот метод выполняет некоторую асинхронную обработку (это , а не AJAX), и в зависимости от результата этой обработки он вызывает либо обратный вызов, либо успешный, либо неудачный.
Вот как это можно схематизировать:
function MyObject() {
}
MyObject.prototype.start = function(successCallback, errorCallback) {
(function(s, e) {
window.setTimeout(function() {
if (Math.random() < 0.8) {
s();
} else {
e();
}
}, 2000);
})(successCallback, errorCallback);
}
Не очень важна точная обработка, выполняемая внутри метода, только то, что она асинхронная и неблокирующая. Я не контролирую момент времени, когда метод start завершит обработку. У меня также нет контроля над прототипом и реализацией этого метода.
Я контролирую обратные вызовы success
и failure
. Это зависит от меня, чтобы обеспечить их.
Теперь у меня есть массив этих объектов:
var arr = [ new MyObject(), new MyObject(), new MyObject() ];
Порядок элементов в этом массиве важен. Мне нужно последовательно вызывать метод .start()
для каждого элемента массива, но только после завершения предыдущего (т. Е. Был вызван обратный вызов успеха). И если происходит ошибка (вызывается обратный вызов сбоя), я хочу остановить выполнение и больше не вызывать метод .start для остальных элементов массива.
Я мог бы реализовать это наивно, используя рекурсивную функцию:
function doProcessing(array, index) {
array[index++].start(function() {
console.log('finished processing the ' + index + ' element');
if (index < array.length) {
doProcessing(array, index);
}
}, function() {
console.log('some error ocurred');
});
}
doProcessing(arr, 0);
Это прекрасно работает, но, глядя на отложенный объект jQuery , который был представлен в jQuery 1.5, я думаю, что есть место для улучшения этого кода. К сожалению, мне пока не очень комфортно с этим, и я пытаюсь научиться этому.
Итак, мой вопрос: можно ли адаптировать мой наивный код и воспользоваться этим новым API, и если да, не могли бы вы дать мне несколько указателей?
Вот jsfiddle с моей реализацией.