Fibras de nodo y devoluciones de llamada asincrónicas
por Neil lobo, Ingeniero de software
Parte de la popularidad de node. js es el bucle de eventos. En lugar de tomar el enfoque multihebrado de los marcos tradicionales, node. js utiliza un modelo de e/S impulsado por eventos y sin bloqueo. Esto le da una huella de memoria más ligera, es más ligero y eficiente, y escala bien para las aplicaciones en tiempo real intensivos en datos.
Este enfoque de no bloqueo impulsado por eventos funciona bien para aplicaciones en las que el cuello de botella es actividad de I/O o red. En cambio, si la aplicación requiere tareas intensivas de CPU, entonces node. js es probablemente una mala opción.
Sin embargo, trabajar con el nodo. js desnudo requiere el uso de devoluciones de llamada asincrónicas que conducen al infierno de devolución de llamada infame. Esto lleva a la lógica que es difícil de seguir
//Callback Soup/Spiral Callback of Doom function doAsync1(function () { doAsync2(function () { doAsync3(function () { doAsync4(function () { //finally do something }); }); }); });
El manejo de errores y las devoluciones de llamada anidadas son incómodas de escribir, y su existencia hace que el código sea difícil de mantener y escalar. Hay algunas técnicas para superar estas cuestiones, las más populares son las fibras y las promesas. Quiero discutir el primero como Meteor utiliza fibras para lograr sincrónico como código sobre el bucle de evento.
Fibras
Para aquellos que no están familiarizados con él, las fibras es una construcción informática que utilizan un modelo de multitarea cooperativa (a diferencia de los hilos de uso de la multitarea preventiva)
El código roscado puede interrumpirse en cualquier punto, incluso en medio de la evaluación de una expresión, para dar ciclos de CPU al código que se ejecuta en otro subproceso. Con las fibras, estas interrupciones y los interruptores de contexto no están determinados por la CPU o un proceso de nivel inferior; son determinadas por el programador que decide dónde va a ceder su código y le dará ciclos de CPU a otras fibras.
Este es un ejemplo de código típico de node. js que utiliza un callbackFunction que se pasa el resultado.
getDataFromDisk = function(fileName, key, callbackFunction) {
var resultado;
fs.readFile('/path/fileName', function(err, res) { if (err) console.log(err); else { result = transform(res, key); callbackFunction(result); }}};
Vamos a apuntar a escribir esto es en un estilo más sincrónico
getDataFromDisk = function(fileName, key) { var result; fs.readFile('/path/fileName', function(err, res) { if (err) console.log(err); else result = transform(res, key);
} resultado de la devolución;// siempre será indefinido }; // Intentamos usar getDataFromDisk para devolver el valor, luego // Imprímelo, todo sincronizado. var = getDataFromDisk('helloWorld',key); console.log(resultado); // indefinido
El código anterior siempre regresará indefinido, ya que el bucle de eventos pasará a la línea de resultado de devolución (*) sin esperar el resultado de la devolución de llamada.
Usando fibras
Las fibras son una clase de funciones de contenedor que se pueden utilizar para bloquear una subrutina mientras se espera una actividad de e/S o de red sin bloquear todo el proceso.
var Fiber = Npm.require('fibers');// getDataFromDisk function using Fibers getDataFromDisk = function(filename, key) {var fiber = Fiber.current; //get the current Fiber fs.readFile('/path/fileName', function(err, res) { if (err) console.log(err); else{ /* Resume execution of this fiber. What’s passed to fiber.run will become the value returned by Fiber.yield below */ fiber.run( transform(res, key) ); var result = Fiber.yield(); return result;}; // Finally we wrap our code in a Fiber, then run it Fiber(function() {
var = getDataFromDisk('helloWorld', key); console.log(resultado); ).run();
Presto, tenemos código de búsqueda sincrónica que todavía se ejecuta de forma asincrónica en el bucle de eventos.
Para más detalles sobre la salida de fibras (https://github.com/laverdet/node-fibers)