De las promesas a los Pipes de promesas

Bruno Pineda
sngular-devs
Published in
4 min readDec 19, 2018

Mas del mágico mundo de FP.

Prefacio.

En mi largo camino del entendimiento de FP que aun me falta por recorrer, he visto un progreso notable y he ganado intuición y es que como la mayoría, vengo de un paradigma de programación distinto, donde por costumbre o intuición usas la manera declarativa sin problema, sin embargo cuando cambias a un paradigma como FP, tienes que cambiar tu intuición a la hora de escribir código.

El camino que me ha funcionado hasta ahora ha sido sin duda, aquel que comienza por el entendimiento de las características mas poderosas que tiene JS, “Closures” y es que cuando se comprende es cuando podemos dar nuestro primer paso.

Dicho camino lo veo como un puente, el cual no te va ahorrar camino que teóricamente deberías recorrer antes, sin embargo la altura de dicho puente te da una visión aérea del camino por seguir y te permite prepararte de una manera mas practica y rápida para tomar el resto del camino cuando el puente de vuelta y te baje donde debiste comenzar.

Y aunque este puente solo te muestre un poco de ese camino, el efecto que tiene es que mejoras la intuición con la visión, es algo como probar una cucharadita de un manjar y que cuando por fin degustas de un poco de ese delicioso platillo…

Mind blown

Exacto, piensas, que otra cosa mas maravillosa podría suceder en ese momento.

Nota: En el articulo titulado “From Closures to Curry and Compose”, escribí el principio de este camino.

Promises

No voy a abarcar mucho en el tema, me voy a enfocar a ejemplos que nos ayudaran a entender la parte siguiente del camino, si quieres sumergirte un poco mas en las promesas o las desconoces, te recomiendo leas “Promises: Beyond callbacks”.

Bien, comencemos por repasar un ejemplo clásico de una promesa, un wait.

Aquí vemos que la promesa se resuelve después de 5 segundos, pero veamos un ejemplo donde el resultado de la primera promesa desencadena las demás, es decir, promesas dependientes una de la anterior.

De manera declarativa lo podemos hacer así.

Pero has pensando que con el camino que hemos recorrido hasta ahora, puedes mejorar esa implementacion, cambiando de declarativo a imperativo y para ello vamos a entender…

Pipes

A diferencia de un “Compose”, pipe usa .reduce() y no .reduceRight(), para lograr su objetivo, el cual es definir una tubería donde pueda ir transmitiendo el resultado y que sea argumento para la siguiente función, evitando el “dot chaining” y favoreciendo el uso del modo imperativo que tanto hemos hablado en estos últimos artículos, por ejemplo.

Bien, ahora traduzcamos esto en modo asíncrono y para ello necesitamos cambiar nuestro pipe para pueda ejecutar promesas, la idea es que la implementacion quede algo parecido a esto:

pip = pipe(p1, p2, p3)(vi);
pip.then(r => console.log(r));

Donde p1, p2 y p3 son las funciones que regresan una promesa y vi es el valor inicial que desencadenara el resultado, finalmente r es el resultado del pipe, el cual al final de ejecutar cada una de esas promesas retornara en forma de promesa.

Primero usamos los parámetros rest para poder representar un numero x de funciones que vamos a pasar como argumentos y aprovechamos de esto para poder aplicar a esa colección de N cantidad funciones un .reduce(), con el cual lograremos realizar el encadenamiento de resultados sin necesidad de exponer el método .then() por cada promesa expresada y de esta manera evitar repetir código.

Dentro del .reduce() f es nuestra primera promesa y la cual necesita el valor inicial representado en este caso como x para cuando resuelva la promesa con un solo .then() desencadenamos la siguiente y así consecutivamente hasta finalizar el ultimo elemento de la colección fns

Regresemos al primer ejemplo de las promesas pero ahora reemplazando la implementacion y usando nuestro pipe.

Y finalmente para consumir el resultado.

Donde r es nuestro resultado final que se fue transformado en la tubería pasando por cada una de las promesas.

Conclusión

Que sigue, bueno hemos llegando al final del puente, el cual recomiendo vuelvas a recorrer una y otra vez hasta contemplar una vista que te haga sentido y veras que el camino continua, sin embargo el entendimiento de FP, te sera menos complicado, aunado a esto también lograras reforzar el entendimiento de los Closures en Javascript.

Los siguientes pasos podría ser que te aventures en tratar de ir realizando mas composición para lograr cambiar de declarativo a imperativo, ejemplo pasar de esto:

const arr = [1, 2, 3];
arr.map(function(item){
//...Do anything
});

a esto:

const arr = [1, 2, 3];
const map = fn => a => a.map(fn);
map((i) => console.log(i))(arr);

Esto solo por poner un ejemplo, la practica te hará ganar intuición al momento de pensar soluciones para escribirlas de manera imperativa.

Siguientes pasos: Composition over Prototypal Inheritance (próximamente).

--

--