-
Notifications
You must be signed in to change notification settings - Fork 0
Procedure Class 2
Simple JS async development, What promise?
La librería soluciona la problemática de tener diversas llamadas a funciones asíncronas, y éstas se necesitan resolver de forma secuencial o por conjuntos, y que cuando finalice la última función en ejecutarse, podamos tener control sobre los resultados. Cada función, para devolver la información de su finalización y datos adicionales, debe realizar como última instrucción
this.done()
.
Con Procedure se declara un Procedimiento, entendiendo un procedimiento como un conjunto de trámites que hay que realizar de forma secuencial y ordenada para completarlo. Una vez estén todos añadidos mediante
.add()
, ejecutamos el procedimiento con.launch()
y se ejecutarán todas las funciones de forma secuencial, es decir, sin asincronismos.
require('procedure');
##Forma básica de crear un procedimiento
Este procedimiento ejecuta secuencialmente a cada función func, llamando a cada función con los parámetros declarados en args. Importante, cada función debe tener como última línea this.done()
;
var procedure = new Procedure({});
procedure
.add(func1, args1)
.add(func2, args2)
.add(func3, args3)
....
.add(funcN, argsN)
.launch();
Se instancia la clase en procedure y mediante .add(*función*, *argumentos*)
se le añade la función a ejecutar junto con los parámetros con los que será llamada. .launch()
lanza el procedimiento, y se comienzan a ejecutar las funciones sin asincronía, es decir, cuando finalice func1, se ejecutará func2, y así hasta que finalice la cola de funciones añadidas al procedimiento.
Si ocurre algún error en la ejecución de alguna de las funciones, se manda el error a .launch().
var procedure = new Procedure(*object*);
- object: objeto de compartirán todos los jobs. this.data; Estos parámetros estarán disponibles para todas las funciones añadidas al procedimiento.
-
.add(func [, args])
: añade al procedimiento una función y si es necesario los argumentos con los que la función será llamada. -
.queue([handler])
: se empaquetan todas las funciones añadidas a procedure, cuando se ejecute.launch()
se ejecutarán todas estas funciones de forma secuencial y ordenada. -
.race([handler])
: se empaquetan todas las funciones añadidas a procedure, cuando se ejecute.launch()
, se ejecutarán todas estas funciones de forma concurrente, y por lo tanto sin orden.
Al callback del método .launch() llegarán errores si los hay, y será llamado cuando finalicen todas y cada una de las funciones que se han añadido.
Las funciones añadidas al procedimiento se pueden empaquetar. Al empaquetar varias funciones especificamos cómo se ejecutarán: si de forma síncrona, mediante .queue()
, o asíncrona mediante .race()
. Todos los paquetes serán ejecutados de forma secuencial cuando se ejecute el método .launch()
.
var procedure = new Procedure();
procedure
.add(func1, args1)
.add(func2, args2)
.add(func3, args3)
.queue()
.add(func4, args4)
.add(func5, args5)
.add(func6, args6)
.race()
.launch(function(error){
if(error){
console.log("One Error:",error);
} else {
console.log("All finished");
}
});
Gracias a la clase Procedure podemos realizar algo impensable en JS, meter un o varias funciones en un bucle y que se ejecuten de forma secuencial.
var procedure = new Procedure();
for(var i=0;i<10;i++){
procedure.add(func,"args["+i+"]");
}
.launch(function(error){
if(error){
console.log("One Error:",error);
} else {
console.log("All finished");
}
});
###Ejemplo 1 Ejemplo funcional de cómo se añaden 5 funciones pasándole diferentes parámetros. Cada función sumará 1 al contador general counter.
var Myhand = function(name){
var job = this;
console.log(name);
job.data.counter++;
job.done();
};
var procedure = new Procedure({counter:10}); // <- Initial data for share.
procedure
.add(Myhand,"Queue[A][1]")
.add(Myhand,"Queue[A][2]")
.add(Myhand,"Queue[A][3]")
.add(Myhand,"Queue[A][4]")
.add(Myhand,"Queue[A][5]")
// Queue execution (in order) of pending jobs.
.queue(function(error){
if(!error){
console.log("Queue[A] finished!");
console.log("Counter:",this.data.counter);
}
})
;
// And finally launch!
procedure
.launch(function(error){
if(error){ // Called by each error.
console.log("One Error:",error);
} else { // Called only if finished whitout errors.
console.log("All finished");
console.log("Counter:",this.data.counter);
}
});
###Ejemplo 2
En este ejemplo vemos como la Clase Procedure permite hacer uso de bucles para añadir el par func,args mediante el método .add()
.
En este ejemplo se añaden 10 funciones y se empaquetan para ser ejecutadas en paralelo mediante el método .race()
. Posteriormente se le añaden otras 10 funciones más y se empaquetan para ser ejecutadas en serie mediante .queue()
.
Se añaden otras 3 funciones más, pero no se empaquetan.
Finalmente mediante .launch()
, se ejecuta el primer paquete programado, luego el segundo, y por último las tres funciones añadidas.
// Add repetitive jobs - Race version
for(var i=0;i<10;i++){ // <- Add repetitive jobs whith variable arguments.
procedure.add(Myhand,"Race[B]["+i+"]");
}
procedure.race(function(error){
if(!error){
console.log("Race[B] finished!");
console.log("Counter:",this.data.counter);
}
});
// Add repetitive jobs - Queue version
for(var i=0;i<10;i++){
procedure.add(Myhand,"Queue[B]["+i+"]");
}
procedure.queue(function(error){
if(!error){
console.log("Queue[B] finished!");
console.log("Counter:",this.data.counter);
}
});
// Add independent jobs
procedure.add(Myhand,"independent[X]");
procedure.add(Myhand,"independent[Y]");
procedure.add(Myhand,"independent[Z]");
// And finally launch!
procedure
.launch(function(error){
if(error){ // Called by each error.
console.log("One Error:",error);
} else { // Called only if finished whitout errors.
console.log("All finished");
console.log("Counter:",this.data.counter);
}
});
Código del ejemplo en JSfiddle
###Ejemplo 3 En este ejemplo vemos que ocurre si hay errores en la ejecución de alguna función.
var Myhand = function(name){
var job = this;
console.log(name);
job.data.counter++;
job.done();
};
// Errors management
var procedure = new Procedure({counter:10}); // <- Initial data for share.
procedure
.add(Myhand,"Queue[C][1]")
.add(Myhand,"Queue[C][2]")
.add(function(){
var job = this;
console.log("Queue[C][3] Throw Error!...");
try {
var a = b;
job.done();
} catch(error) {
job.error(error);
}
})
.add(Myhand,"Queue[C][4]")
.add(Myhand,"Queue[C][5]")
.launch(function(error){
if(error){
console.log("One Error:",error);
} else {
console.log("All finished");
console.log("Counter:",this.data.counter);
}
});
Código del ejemplo en JSfiddle
#Licencia MIT