Sé que esto probablemente ya se ha preguntado antes, pero viniendo del lenguaje de subproceso único durante los últimos 20 años, realmente estoy luchando por comprender la verdadera naturaleza de node. créanme, he leído un montón de publicaciones de SO, discusiones de github y artículos sobre esto.
Creo que entiendo que cada función tiene su propio tipo de trato. sin embargo, hay algunos casos en los que quiero que mi código sea completamente sincrónico (activar una función tras otra).
por ejemplo, hice 3 funciones que parecen mostrarme cómo funciona la E/S asíncrona del nodo:
function sleepA() { setTimeout(() => { console.log('sleep A') }, 3000) } function sleepB() { setTimeout(() => { console.log('sleep B') }, 2000) } function sleepC() { setTimeout(() => { console.log('sleep C') }, 1000) } sleepA() sleepB() sleepC()esto genera lo siguiente:
sleep C sleep B sleep Abien, eso tiene sentido. el nodo activa todas las funciones al mismo tiempo, y las que se completen primero se registran en la consola. algo así como ver carreras de caballos. node dispara un arma y las funciones despegan, y gana el más rápido.
Entonces, ¿ cómo haría para que sean síncronos para que el orden sea siempre A, B, C , independientemente del número de setTimeout?
He incursionado con cosas como bluebird y la biblioteca de nodos util y todavía estoy un poco confundido. Creo que esta lógica asíncrona es increíblemente poderosa a pesar de mi incapacidad para comprenderla realmente. php ha destruido mi mente.
¿Cómo haría para hacerlos sincrónicos para que el orden sea siempre A, B, C?
Ha confirmado que lo que quiere decir con eso es que no desea iniciar el tiempo de espera para B hasta que A haya terminado (etc.).
Aquí, en 2021, la forma más fácil de hacerlo es usar un contenedor habilitado para promesas para setTimeout , como este:
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); Luego, haga sleepA y tales funciones async :
async function sleepA() { await delay(3000); console.log("sleep A"); } async function sleepB() { await delay(2000); console.log("sleep B"); } async function sleepC() { await delay(1000); console.log("sleep C"); } Luego, su código puede await la promesa que devuelve cada una de esas funciones, lo que evita que el código continúe hasta que se resuelva la promesa:
await sleepA(); await sleepB(); await sleepC(); Puede hacerlo dentro de una función async o (en versiones modernas de Node.js) en el nivel superior de un módulo. No puede usar await en una función síncrona, ya await es asíncrono por naturaleza.
creo que entiendo que cada función tiene su propio tipo de trato de hilo
No, las funciones de JavaScript son como las de otros lenguajes síncronos (a pesar de su reputación, JavaScript en sí mismo es abrumadoramente síncrono; solo se usa en entornos altamente asíncronos y recientemente obtuvo algunas características para hacerlo más fácil). Más sobre esto a continuación.
bien, eso tiene sentido. el nodo activa todas las funciones al mismo tiempo, y las que se completen primero se registran en la consola. algo así como ver carreras de caballos. node dispara un arma y las funciones despegan, y gana el más rápido.
Cerca. Las funciones se ejecutan en orden, pero todo lo que hace cada una de ellas es configurar un temporizador y regresar. No esperan a que se dispare el temporizador. Más tarde, cuando se activa, llama a la devolución de llamada que pasaste a setTimeout .
JavaScript tiene un subproceso principal y todo se ejecuta en ese subproceso principal, a menos que lo haga explícitamente ejecutar en un subproceso de trabajo o en un proceso secundario. Node.js es altamente asincrónico (al igual que los navegadores web, el otro lugar donde se usa principalmente JavaScript), pero su código JavaScript se ejecuta en un hilo de forma predeterminada. Hay un bucle que procesa "trabajos". Los trabajos se ponen en cola por eventos (como la activación de un temporizador) y luego se procesan en orden por el bucle de eventos. Profundizo un poco más aquí , y la documentación de Node.js cubre su ciclo aquí (creo que está un poco desactualizado, pero el director no ha cambiado) .