Mam standardowy obiekt javascript, którego prototyp jest rozszerzany o metodę .start()
, przyjmującą 2 wywołania zwrotne odpowiednio jako argumenty: success
i failure
. Ta metoda wykonuje pewne asynchroniczne przetwarzanie (jest to A31X), a w zależności od wyniku tego przetwarzania wywołuje zarówno powodzenie, jak i niepowodzenie wywołania zwrotnego.Jak korzystać z odroczonego obiektu jQuery za pomocą niestandardowych obiektów javascript?
Oto jak można to schematycznie:
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);
}
To naprawdę nie jest ważne dokładne przetwarzanie wykonywane wewnątrz metody, tylko że to jest asynchroniczne i bez blokowania. Nie mam kontroli nad momentem, w którym metoda początkowa zakończy przetwarzanie. Nie mam też kontroli nad prototypem i wdrożeniem tej metody.
Mam kontrolę nad połączeniami zwrotnymi success
i failure
. To zależy od mnie, aby je zapewnić.
Teraz mam tablicę tych obiektów:
var arr = [ new MyObject(), new MyObject(), new MyObject() ];
Kolejność elementów w tej tablicy jest bardzo ważne. Potrzebuję wywołać metodę .start()
na każdym elemencie tablicy kolejno, ale tylko po zakończeniu poprzedniego (to jest wywołanie zwrotne sukcesu). A jeśli wystąpi błąd (wywoływane jest wywołanie zwrotne niepowodzenia) Chcę zatrzymać wykonywanie i nie wywołuję metody .start na pozostałych elementach tablicy.
mogłaby wdrożyć to naiwnie za pomocą funkcji rekurencyjnej:
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);
Działa to dobrze, ale patrząc na jQuery's deferred Object, który został wprowadzony w jQuery 1.5 Myślę, że istnieje możliwość poprawy tego kodu. Niestety nie czuję się jeszcze z nim dobrze i staram się go nauczyć.
Moje pytanie brzmi: czy możliwe jest dostosowanie mojego naiwnego kodu i skorzystanie z tego nowego API, a jeśli tak, czy mógłbyś podać mi jakieś wskazówki?
Oto jsfiddle z moją implementacją.
+1 Zawsze dobrze jest zobaczyć górną odpowiadającego prosząc dobre pytanie. Samodzielna odpowiedź na to pytanie? –