Как использовать отложенный объект jQuery с пользовательскими объектами javascript?

У меня есть стандартный объект 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's deferred Object, который был представлен в jQuery 1.5, я думаю, что есть место для улучшения этого кода. К сожалению, я пока не чувствую себя очень комфортно с ним и пытаюсь его изучить.

Так что мой вопрос, возможно ли адаптировать мой наивный код и воспользоваться преимуществами этого нового API, и если да, не могли бы вы дать мне несколько указателей?

Вот jsfiddle с моей реализацией.

13
задан Darin Dimitrov 12 October 2011 в 17:19
поделиться