He leído toneladas de artículos y documentos, sin embargo, este tema aún no es lo suficientemente claro para mí. Cita de una respuesta https://stackoverflow.com/a/46004461/630169:

Mientras el código contenido dentro del async / await no se bloquee, no bloqueará, por ejemplo, llamadas db, llamadas de red, llamadas al sistema de archivos.

Pero si el código contenido en async / await está bloqueando, bloqueará todo el proceso Node.js, por ejemplo, bucles infinitos, tareas intensivas de CPU como procesamiento de imágenes, etc.

Sin embargo, Comprensión del bucle de eventos node.js dice:

Por supuesto, en el backend, hay subprocesos y procesos para el acceso a la base de datos y la ejecución del proceso.

En C # es suficiente escribir la función marcada con async y llamar con await para que .Net la coloque en otro hilo. Sin embargo, me confundió cosas organizadas de manera diferente en Node.js y la función async / await todavía podría bloquear el hilo principal.

Entonces, la pregunta es: ¿cómo escribir (organizar) la función async/await arbitraria en node.js para asegurarse de que se ejecutará de forma asincrónica en un hilo o proceso separado? ¿Hay un buen código de ejemplo? ¿Algún módulo npm? También es bueno que no sea mucho más complicado que la variante C #. ¡Gracias!

Algunos ejemplos de funciones lo hicieron sin bloqueo, por ejemplo, si quiero que una llamada DB sincrónica se haga asincrónica (sin bloqueo):

var Database = require('better-sqlite3');

var db = new Database('./my_db.sqlite');

async function DBRequest() {
    var row = db.prepare("SELECT * FROM table");
    return row;
};

Nota: better-sqlite3 - módulo síncrono.

1
Aleksey Kontsevich 31 oct. 2017 a las 13:23

3 respuestas

La mejor respuesta

Mi interés no era por nada: preguntas similares la gente me hizo antes que yo, también como en stackoverflow (y aquí):

¿Pero qué pasa con las tareas largas y vinculadas a la CPU?

¿Cómo evita bloquear el bucle de eventos, cuando la tarea está a mano no está vinculada a E / S y dura más de unas pocas fracciones de milisegundo? Simplemente no puede, porque no hay manera ... bueno, no había antes threads_a_gogo.

Y para resolverlos, ya han creado un montón de módulos, y algunos, como threads, funciona tanto en el navegador como en Node.js:

Bueno, si alguien pudiera adjuntar async/await a ellos o dar un buen ejemplo, sería bueno.

Por cierto, aquí hay una prueba de camarada basada en Threads à gogo - resultados con los hilos son 40 veces más rápido que con Clúster. Entonces, la idea de un solo subproceso de Node.js no siempre funciona bien.

0
Aleksey Kontsevich 1 nov. 2017 a las 11:44

Bueno, aquí hay un código de ejemplo. Decidió que valía la pena realizarlo.

Puede escribir código de bloqueo de larga ejecución de tal manera que pueda generar tiempo de ejecución para otras funciones

var array = new Array(100);
function processNext(){
    if (array.length === 0) return;
    var item = array.shift(); // gets first item from array and removes it.
    process(item); // 0.5 seconds of blocking time
    setTimeout(processNext ,500); // wait 0.5 seconds and then process the next one
    // during this waiting time, other code will run on your server.
}

processNext();

Es cierto que soy un novato y esta puede ser una muy mala idea por razones que no conozco.

0
TKoL 31 oct. 2017 a las 10:35

Estás realmente a merced de la biblioteca que estás usando aquí: si el código es sincrónico y no está vinculado a E / S, entonces realmente no hay mucho más que puedas hacer dentro de tu proceso de Nodo para hacerlo asíncrono.

Su única alternativa real es mover ese código a su propio proceso, lo que en consecuencia lo vincula a E / S, de esa manera su aplicación puede esperar y no bloquear su propio hilo.

0
James 31 oct. 2017 a las 11:54