Ho un oggetto javascript standard il cui prototipo è esteso con un metodo .start()
che accetta 2 callback come argomenti: success
e failure
rispettivamente. Questo metodo esegue un'elaborazione asincrona (è non AJAX) e in base al risultato di questa elaborazione richiama il callback di esito positivo o di errore.Come utilizzare l'oggetto posticipato di jQuery con oggetti javascript personalizzati?
Ecco come questo potrebbe essere schematizzato:
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);
}
Non è veramente importante trattamento esatto eseguito all'interno del metodo, solo che è asincrono e non bloccante. Non ho il controllo sul momento in cui il metodo di avvio terminerà l'elaborazione. Inoltre, non ho alcun controllo sul prototipo e sull'implementazione di questo metodo.
Quello di cui ho il controllo sono i callback success
e failure
. Spetta a me fornirli.
ora ho un array di tali oggetti:
var arr = [ new MyObject(), new MyObject(), new MyObject() ];
L'ordine degli elementi in questo array è importante. Devo attivare il metodo .start()
su ogni elemento dell'array in modo consecutivo, ma solo una volta che il precedente è stato completato (cioè è stato chiamato il callback di successo). E se si verifica un errore (viene chiamato il callback di errore), voglio interrompere l'esecuzione e non richiamare più il metodo .start sugli altri elementi dell'array.
ho potuto implementare questa ingenuamente utilizzando una funzione ricorsiva:
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);
Questo funziona bene, ma guardando il jQuery's deferred Object che è stato introdotto in jQuery 1.5 Penso che ci sia un margine di miglioramento di questo codice. Purtroppo non mi sento molto a mio agio con esso e sto cercando di impararlo.
Quindi la mia domanda è: è possibile adattare il mio codice naive e sfruttare questa nuova API e se sì, potresti fornirmi alcuni suggerimenti?
Ecco uno jsfiddle con la mia implementazione.
+1 sempre bello vedere un top risposto chiedendo una buona domanda. Rispondendo da solo a questo? –