Skip to content

Commit c621daf

Browse files
authored
Merge pull request #503 from joaquinelio/promi
actualizacion promisify cierra #442
2 parents 69d1959 + f2bbc15 commit c621daf

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

1-js/11-async/06-promisify/article.md

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# Promisification
1+
# Promisificación
22

3-
Promisification (Promisificación) -- es una palabra larga para una simple transformación. Es una conversión: de una función que acepta un callback a una función que retorna una promesa.
3+
"Promisificación" es una simple transformación. Es la conversión de una función que acepta un callback a una función que devuelve una promesa.
44

5-
En otras palabras, creamos una función de envoltura que realiza lo mismo, llamando a la original internamente, pero retornando una promesa.
5+
A menudo estas transformaciones son necesarias en la vida real ya que muchas funciones y librerías están basadas en callbacks, pero las promesas son más convenientes así que tiene sentido promisificarlas.
66

7-
Estas transformaciones son usualmente necesarias en la vida real, ya que muchas funciones y librerías están basadas en callbacks. Pero las promesas son mas convenientes, así que tiene sentido promisificar.
7+
Veamos un ejemplo.
88

9-
Por ejemplo, tenemos `loadScript(src, callback)` del capítulo <info:callbacks>.
9+
Aquí tenemos `loadScript(src, callback)` del artículo <info:callbacks>.
1010

1111
```js run
1212
function loadScript(src, callback) {
1313
let script = document.createElement('script');
1414
script.src = src;
1515

1616
script.onload = () => callback(null, script);
17-
script.onerror = () => callback(new Error(`Error de carga de script para ${src}`));
17+
script.onerror = () => callback(new Error(`Error de carga de script ${src}`));
1818

1919
document.head.append(script);
2020
}
@@ -23,9 +23,15 @@ function loadScript(src, callback) {
2323
// loadScript('path/script.js', (err, script) => {...})
2424
```
2525

26-
Vamos a promisificarla. La función nueva `loadScriptPromise(src)` va a hacer lo mismo, pero solo acepta `src` (sin callback) y retorna una promesa.
26+
La función carga un script con el `src` dado, y llama a `callback(err)` en caso de error o `callback(null, script)` en caso de carga exitosa. Esto está ampliamente acordado en el uso de callbacks, lo hemos visto antes.
2727

28-
Aquí:
28+
Vamos a promisificarla.
29+
30+
Haremos una función nueva `loadScriptPromise(src)` que va a hacer lo mismo (carga el script), pero devuelve una promesa en vez de usar callbacks.
31+
32+
Es decir: pasamos solamente `src` (sin `callback`) y obtenemos una promesa de vuelta, que resuelve con `script` cuando la carga fue exitosa y rechaza con error en caso contrario.
33+
34+
Aquí está:
2935
```js
3036
let loadScriptPromise = function(src) {
3137
return new Promise((resolve, reject) => {
@@ -40,21 +46,19 @@ let loadScriptPromise = function(src) {
4046
// loadScriptPromise('path/script.js').then(...)
4147
```
4248

43-
Ahora `loadScriptPromise` se ajusta bien a nuestro código basado en promesas.
49+
Como podemos ver, la nueva función es un "wrapper" (una función contenedora) que envuelve la función `loadScript` original. La llama proveyendo su propio callback y la traduce a una promesa `resolve/reject`.
4450

45-
Como podemos ver, le delega todo el trabajo a la función `loadScript` original, proveyendo su propio callback que es traducido a promise `resolve/reject`.
51+
Ahora `loadScriptPromise` se adapta bien a un código basado en promesas. Si nos gustan más las promesas que los callbacks (y pronto veremos más motivos para ello), la usaremos en su lugar.
4652

47-
Como vamos a tener que promisificar muchas funciones, tiene sentido usar un ayudante.
53+
En la práctica podemos necesitar promisificar más de una función, así que tiene sentido usar un ayudante.
4854

49-
Esto es en realidad muy simple -- La función `promisify(f)` debajo toma una función `f` que sera promisificada y retorna una función de envoltura (wrapper function).
50-
51-
Esa envoltura realiza lo mismo que el código de arriba: retorna una promesa y pasa el llamado a la `f` original, rastreando el resultado en un callback personalizado.
55+
Lo llamamos `promisify(f)`: esta acepta la función a promisificar `f` y devuelve una función contenedora (wrapper).
5256

5357
```js
5458
function promisify(f) {
55-
return function (...args) { // retorna una función de envoltura
59+
return function (...args) { // devuelve una función contenedora (*)
5660
return new Promise((resolve, reject) => {
57-
function callback(err, result) { // nuestro callback personalizado para f
61+
function callback(err, result) { // nuestro callback personalizado para f (**)
5862
if (err) {
5963
reject(err);
6064
} else {
@@ -74,11 +78,18 @@ let loadScriptPromise = promisify(loadScript);
7478
loadScriptPromise(...).then(...);
7579
```
7680

77-
Aquí asumimos que la función original espera un callback con dos argumentos `(err, result)`. Eso es lo que usualmente encontramos. Entonces nuestro callback personalizado está exactamente en el formato correcto, y `promisify` funciona muy bien para tal caso.
81+
El código puede verse complicado, pero es esencialmente lo mismo que escribimos arriba al promisificar la función `loadScript`.
82+
83+
Una llamada a `promisify(f)` devuelve una función contenedora que envuelve a `f` `(*)`. Este contenedor devuelve una promesa y redirige el llamado a la `f` original, siguiendo el resultado en el callback personalizado `(**)`.
84+
85+
Aquí `promisify` asume que la función original espera un callback con dos argumentos `(err, result)`. Eso es lo que usualmente encontramos. Entonces nuestro callback personalizado está exactamente en el formato correcto, y `promisify` funciona muy bien para tal caso.
7886

7987
¿Y si la `f` original espera un callback con más argumentos `callback(err, res1, res2)`?
8088

81-
Aquí hay una modificación de `promisify` que retorna un array de los múltiples resultados del callback:
89+
Podemos mejorar el ayudante. Hagamos una versión de `promisify` más avanzada.
90+
91+
- Cuando la llamamos como `promisify(f)`, debe funcionar igual que en la versión previa.
92+
- Cuando la llamamos como `promisify(f, true)`, debe devolver una promesa que resuelve con el array de resultados del callback. Esto es para callbacks con muchos argumentos.
8293

8394
```js
8495
// promisify(f, true) para conseguir array de resultados
@@ -89,7 +100,7 @@ function promisify(f, manyArgs = false) {
89100
if (err) {
90101
reject(err);
91102
} else {
92-
// Retornar todos los resultados del callback si manyArgs es especificado
103+
// Devolver todos los resultados del callback si "manyArgs" es especificado
93104
*!*resolve(manyArgs ? results : results[0]);*/!*
94105
}
95106
}
@@ -105,12 +116,15 @@ function promisify(f, manyArgs = false) {
105116
f = promisify(f, true);
106117
f(...).then(arrayOfResults => ..., err => ...);
107118
```
108-
En algunos casos, puede que `err` esté ausente: `callback(result)`, o que haya algo que no es habitual en el formato del callback, por lo que tendremos que promisificar tales funciones manualmente.
119+
120+
Como puedes ver es esencialmente lo mismo de antes, pero `resolve` es llamado con solo uno o con todos los argumentos dependiendo del valor de `manyArgs`.
121+
122+
Para formatos más exóticos de callback, como aquellos sin `err` en absoluto: `callback(result)`, podemos promisificarlos manualmente sin usar el ayudante.
109123
110124
También hay módulos con funciones de promisificación un poco más flexibles, ej. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify). En Node.js, hay una función integrada `util.promisify` para ello.
111125
112126
```smart
113-
La promisificación es un excelente enfoque, especialmente cuando usas `async/await` (revisa el siguiente capítulo), pero no es totalmente un substituto para los callbacks.
127+
La promisificación es un excelente enfoque, especialmente cuando usas `async/await` (revisa el siguiente artículo), pero no es un substituto completo para los callbacks.
114128

115129
Recuerda, una promesa puede tener sólo un resultado, pero un callback puede ser técnicamente llamado muchas veces.
116130

0 commit comments

Comments
 (0)