javascript - Cómo escribir funciones asíncronas para Node.js
asynchronous (5)
Intenté investigar cómo deberían escribirse exactamente las funciones asíncronas. Después de analizar una gran cantidad de documentación, todavía no está claro para mí.
¿Cómo escribo funciones asíncronas para Node? ¿Cómo debo implementar el manejo de eventos de error correctamente?
Otra forma de hacer mi pregunta sería esta: ¿cómo debo interpretar la siguiente función?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
Además, encontré esta pregunta en SO ("¿Cómo creo una función asincrónica sin bloqueo en node.js?") Interesante. No siento que haya sido respondida todavía.
Debería ver esto: episodio 19 de Node Tuts - Patrones de iteración asíncrona
Debería responder tus preguntas.
Parece que confunde IO asíncrona con funciones asíncronas. node.js usa IO no bloqueante asincrónico porque IO no bloqueado es mejor. La mejor forma de entenderlo es ir a ver algunos videos de ryan dahl.
¿Cómo escribo funciones asíncronas para Node?
Simplemente escriba funciones normales, la única diferencia es que no se ejecutan de inmediato sino que se pasan como devoluciones de llamada.
¿Cómo debo implementar correctamente el manejo de eventos de error?
En general, las API le otorgan una devolución de llamada con un error como primer argumento. Por ejemplo
database.query(''something'', function(err, result) {
if (err) handle(err);
doSomething(result);
});
Es un patrón común.
Otro patrón común es on(''error'')
. Por ejemplo
process.on(''uncaughtException'', function (err) {
console.log(''Caught exception: '' + err);
});
Editar:
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
La función anterior cuando se llama como
async_function(42, function(val) {
console.log(val)
});
console.log(43);
Imprimirá 42
en la consola de forma asíncrona. En particular, process.nextTick
activa después de que la pila de llamadas de evento actual esté vacía. Esa pila de llamadas está vacía después de async_function
y async_function
console.log(43)
. Entonces imprimimos 43 seguido por 42.
Probablemente deberías leer un poco sobre el ciclo de eventos.
Pruebe esto, funciona tanto para el nodo como para el navegador.
isNode = (typeof exports !== ''undefined'') &&
(typeof module !== ''undefined'') &&
(typeof module.exports !== ''undefined'') &&
(typeof navigator === ''undefined'' || typeof navigator.appName === ''undefined'') ? true : false,
asyncIt = (isNode ? function (func) {
process.nextTick(function () {
func();
});
} : function (func) {
setTimeout(func, 5);
});
Si SABES que una función devuelve una promesa, te sugiero que uses las nuevas funciones async / await en JavaScript. Hace que la sintaxis parezca síncrona pero funcione de forma asíncrona. Cuando agrega la palabra clave async
a una función, le permite await
promesas en ese ámbito:
async function ace() {
var r = await new Promise((resolve, reject) => {
resolve(true)
});
console.log(r); // true
}
si una función no devuelve una promesa, recomiendo envolverla en una nueva promesa que defina y luego resolver los datos que desee:
function ajax_call(url, method) {
return new Promise((resolve, reject) => {
fetch(url, { method })
.then(resp => resp.json())
.then(json => { resolve(json); })
});
}
async function your_function() {
var json = await ajax_call(''www.api-example.com/some_data'', ''GET'');
console.log(json); // { status: 200, data: ... }
}
En pocas palabras: aproveche el poder de Promises.
Solo pasar devoluciones de llamada no es suficiente. Tienes que usar settimer por ejemplo, para hacer la función async.
Ejemplos: funciones no sincronizadas:
function a() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
};
function b() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
};
function c() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
};
a();
console.log("This should be good");
Si ejecuta el ejemplo anterior, esto debería ser bueno, tendrá que esperar hasta que esas funciones terminen de funcionar.
Funciones Pseudo Multithread (async):
function a() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
}, 0);
};
function b() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
}, 0);
};
function c() {
setTimeout ( function() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
}, 0);
};
a();
console.log("This should be good");
Este será realmente asincrónico. Esto debería ser bueno será escrito antes de que se acabe la sincronización.