Tengo un objeto javascript estándar cuyo prototipo se extiende con un método .start()
tomando 2 devoluciones de llamada como argumentos: success
y failure
respectivamente. Este método realiza un procesamiento asincrónico (es no AJAX) y, dependiendo del resultado de este procesamiento, invoca las devoluciones de llamada correctas o fallidas.Cómo usar el objeto diferido de jQuery con objetos JavaScript personalizados?
Así es como esto podría ser esquematizada:
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);
}
No es realmente importante el procesamiento exacta realizada dentro del método, sólo que es asíncrona y sin bloqueo. No tengo control sobre el momento en que el método de inicio terminará el procesamiento. Tampoco tengo control sobre el prototipo y la implementación de este método.
Lo que tengo control es el success
y failure
devoluciones de llamada. Depende de mí proporcionarlos.
Ahora I tienen una serie de dichos objetos:
var arr = [ new MyObject(), new MyObject(), new MyObject() ];
El orden de los elementos de esta matriz es importante. Necesito activar el método .start()
en cada elemento de la matriz de forma consecutiva, pero solo una vez que se haya completado la anterior (es decir, se llamó a la devolución de llamada exitosa). Y si ocurre un error (se llama a la devolución de llamada fallida) quiero detener la ejecución y no invocar el método .start en los elementos restantes de la matriz.
pude poner en práctica esta ingenua mediante el uso de una función recursiva:
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);
Esto funciona bien, pero mirando el jQuery's deferred Object que se introdujo en jQuery 1.5 Creo que hay un margen de mejora de este código. Lamentablemente, aún no me siento muy cómodo con eso y estoy tratando de aprenderlo.
Así que mi pregunta es si es posible adaptar mi código ingenuo y aprovechar esta nueva API y, en caso afirmativo, ¿podría darme algunos consejos?
Aquí hay un jsfiddle con mi implementación.
1 siempre es bueno ver un contestador arriba haciendo una buena pregunta. ¿Respondiendo uno a este? –