Suponga que mantiene una biblioteca que expone una función getData
. Sus usuarios lo llaman para obtener datos reales:
var output = getData();
los datos internos se guardan en un archivo para que los implemente getData
utilizando Node.js integrado fs.readFileSync
. Es obvio tanto getData
y fs.readFileSync
son funciones de sincronización. Un día le dijeron que cambiara la fuente de datos subyacente a un repositorio como MongoDB, al que solo se puede acceder de forma asincrónica. También se le dijo que evitara enojar a sus usuarios, la getData
API no se puede cambiar para devolver simplemente una promesa o exigir un parámetro de devolución de llamada. ¿Cómo cumple ambos requisitos?
La función asincrónica que usa callback / promise es el ADN de JavasSript y Node.js. Cualquier aplicación JS no trivial probablemente esté impregnada de este estilo de codificación. Pero esta práctica puede conducir fácilmente a la llamada pirámide de la fatalidad. Peor aún, si algún código en cualquier llamador en la cadena de llamadas depende del resultado de la función asíncrona, ese código también debe estar incluido en la función de devolución de llamada, imponiendo una restricción de estilo de codificación al llamador. De vez en cuando, encuentro la necesidad de encapsular una función asíncrona (a menudo proporcionada en una biblioteca de terceros) en una función de sincronización para evitar una refactorización global masiva. La búsqueda de una solución sobre este tema generalmente terminaba con Node Fiberso paquetes npm derivados de él. Pero las fibras simplemente no pueden resolver el problema al que me enfrento. Incluso el ejemplo proporcionado por el autor de Fibers ilustra la deficiencia:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
Salida real:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
Si la función Fiber realmente convierte la función asíncrona en reposo en sincronizada, la salida debería ser:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
Creé otro ejemplo simple en JSFiddle y busqué código para producir el resultado esperado. Aceptaré una solución que solo funcione en Node.js, por lo que puede solicitar cualquier paquete npm a pesar de no funcionar en JSFiddle.