‫Instructor: Tomemos ahora un minuto para aprender sobre
‫la naturaleza asincrónica de Node. js,
‫que incluye temas absolutamente fundamentales,
‫como código sincrónico, asincrónico, bloqueante
‫y no bloqueante.
‫Y todo esto será realmente importante para
‫comprender todo lo que se presenta a lo largo
‫de esta sección.
‫Entonces, este fragmento de código que escribimos en la
‫última lección, para leer un archivo y luego, guardar su contenido en
‫una variable, fue de una manera llamada
‫síncrona, lo que simplemente significa
‫que cada declaración se procesa básicamente una tras otra, línea nombre del autor.
‫En este ejemplo,
‫primero, se requiere el módulo del sistema de
‫archivos, luego, se lee el
‫archivo y luego, registramos el resultado en la consola.
‫Entonces ves que cada línea
‫de código básicamente espera el resultado de la línea anterior.
‫Ahora, esto puede convertirse en un
‫problema, especialmente con operaciones lentas,
‫porque cada línea bloquea la ejecución del
‫resto del código.
‫Entonces, decimos que el código
‫síncrono también se llama código de bloqueo porque, nuevamente, una
‫determinada operación solo se puede ejecutar después
‫de que la anterior haya terminado.
‫Y debido a la forma en que Node. js fue diseñado,
‫esto se convierte en un gran problema, como veremos
‫en detalle en la siguiente diapositiva.
‫Entonces, la solución a este
‫problema en Node es usar código asincrónico sin bloqueo.
‫Entonces, en código asincrónico, cargamos trabajo pesado
‫para básicamente trabajar en segundo plano.
‫Y luego, una vez que se realiza
‫ese trabajo, se llama a una función de devolución
‫de llamada que registramos antes para manejar el resultado.
‫Y durante todo ese
‫tiempo, el resto del código puede seguir ejecutándose
‫sin ser bloqueado por la tarea
‫pesada, que ahora se ejecuta en segundo plano.
‫Entonces, lo que esto significa es que podemos diferir o
‫reaccionar de manera efectiva en
‫el futuro para que el código no
‫se bloquee y esto, por supuesto, es mucho mejor.
‫¿Tiene sentido?
‫Entonces, en este ejemplo, usamos la
‫función readFile asincrónica, que acepta una función de devolución de llamada.
‫Esto comenzará a leer el archivo en
‫segundo plano y luego, inmediatamente pasará a la siguiente declaración,
‫imprimiendo en la consola el archivo de lectura de cadenas.
‫Entonces, nuevamente, ya ve, no estamos bloqueando la ejecución aquí.
‫Luego, cuando el archivo finalmente se lea por completo, se llamará
‫a la función de devolución de
‫llamada y, por lo tanto, los datos que
‫se leyeron se imprimirán en la consola.
‫Entonces eso es bastante diferente
‫de la versión sincrónica, ¿no es así?
‫Ahora, la pregunta aquí
‫es, ¿por qué tiene que ser así?
‫¿Cuál es el problema con el bloqueo de la ejecución de código en Node. js?
‫O, en otras palabras, ¿por qué usamos la devolución de llamada
‫tantas veces en Node. js?
‫Bueno, averigüémoslo.
‫Y para comprender estas preguntas, lo primero
‫que debemos comprender es el hecho
‫de que Node. js, que
‫es donde se ejecuta nuestra
‫aplicación, solo hay un hilo.
‫Y el hilo es como un conjunto de instrucciones que se
‫ejecutan en la CPU de la computadora.
‫Básicamente, el hilo es donde nuestro
‫código se ejecuta realmente en el procesador de una máquina.
‫Entonces, recuerda, Node. js es básicamente de un
‫solo subproceso y, por lo tanto, para cada aplicación, solo hay un subproceso.
‫Esa es la forma en que Node. js fue diseñado.
‫Ahora, lo que eso significa es que
‫todos los usuarios que acceden a su aplicación están usando el
‫mismo hilo, así que, básicamente, acceden al mismo hilo.
‫Y así, cada vez que interactúan con la aplicación, el
‫código que se ejecuta para cada
‫usuario se ejecutará en el mismo hilo en el mismo lugar
‫en la computadora que ejecuta la aplicación.
‫Y eso es cierto sin importar
‫si tiene cinco usuarios, como en este diagrama, o 5,000 o 5 millones.
‫¿Está bien?
‫Ahora, lo que esto también significa es que cuando
‫un usuario bloquea el hilo único con código
‫síncrono, como acabamos de
‫ver antes, todos los demás usuarios tendrán que
‫esperar a que finalice la ejecución.
‫Y eso podría no ser un
‫gran problema si tiene cinco usuarios, pero
‫definitivamente lo será para miles o incluso millones de
‫usuarios al mismo tiempo.
‫Entonces, imagina que hay un usuario accediendo a tu
‫aplicación y hay un enorme archivo síncrono leído en tu
‫código que tardará como un segundo en cargarse.
‫Esto significará, por supuesto, que durante ese
‫segundo, todos los demás usuarios
‫tendrán que esperar porque toda la ejecución está bloqueada durante ese segundo.
‫Entonces, si esos otros usuarios quieren hacer algunas
‫tareas simples, como iniciar sesión
‫en su aplicación o simplemente solicitar algunos datos, no podrán hacerlo.
‫Tendrán que esperar hasta que el archivo termine de leerse.
‫Solo cuando eso suceda, finalmente podrán realizar las tareas
‫más simples, una tras otra.
‫Ahora, tenga en cuenta que esta es una versión muy simplificada de lo que realmente
‫sucede detrás de escena de Node. js, por lo
‫que volveremos a todo esto en
‫la siguiente sección y obtendremos una comprensión aún
‫más profunda de cómo Node. js maneja el código asincrónico bajo el capó.
‫Pero en este
‫punto, esto es suficiente para que comprenda el concepto.
‫Es mejor ir paso a paso
‫aquí y no hacerlo
‫demasiado confuso desde el principio, ¿de acuerdo?
‫De todos modos, así es como
‫se desarrollaría la situación con el código de
‫bloqueo síncrono, que obviamente es una experiencia terrible para sus usuarios.
‫Por lo tanto, es realmente su trabajo como desarrollador
‫evitar este tipo de situaciones mediante
‫el uso de código asincrónico.
‫Entonces, para la misma situación, deberíamos, por supuesto, usar
‫la función de lectura de archivo asincrónica, que
‫en lugar de bloquear el
‫hilo único, hace el trabajo pesado en
‫segundo plano, donde básicamente permanece hasta que
‫termina de leer los datos del archivo.
‫Por supuesto, también registramos una función de devolución de
‫llamada que se llamará una vez que los datos estén disponibles.
‫Y en este escenario, todos los demás
‫usuarios pueden realizar sus tareas en un solo
‫hilo, uno tras otro, mientras el archivo todavía se está
‫leyendo en segundo plano.
‫Ahora, una vez que se leen los datos, nuestra función de
‫devolución de llamada, por supuesto, se
‫llamará para que se ejecute en el hilo principal único para procesar los datos leídos.
‫Y eso es.
‫Esa es una descripción general de cómo Node. js maneja
‫el comportamiento asincrónico para implementar el modelo de E
‫/ S sin bloqueo del que hablamos
‫en la lección de introducción, ¿de acuerdo?
‫Y E / S simplemente significa entrada-salida, que
‫es básicamente cosas como acceder al sistema de
‫archivos y manejar solicitudes de red.
‫En realidad, esta es la razón por la que Node. js está completamente
‫diseñado en torno a devoluciones de llamada,
‫como verá a lo largo del curso.
‫En otros lenguajes de programación, como PHP, funciona
‫de manera muy diferente porque obtienes, básicamente, un hilo
‫nuevo para cada nuevo usuario, lo
‫cual es un paradigma completamente diferente
‫y realmente funciona de manera completamente diferente.
‫Pero el creador de Node. js encontró que
‫este modelo es la mejor solución para crear
‫aplicaciones web escalables y de alto rendimiento.
‫Ahora, solo como nota final aquí, es importante saber que,
‫cuando usamos devoluciones de
‫llamada en nuestro código, eso no lo hace automáticamente asíncrono, ¿de acuerdo?
‫Entonces, pasar funciones a otras funciones
‫es bastante común en
‫JavaScript, pero por supuesto, nuevamente, eso
‫no las hace asincrónicas automáticamente, ¿de acuerdo?
‫Solo funciona de esta manera para algunas funciones en la API de nodo,
‫como la función readFile y muchas,
‫muchas más, a medida que la gente explore en el futuro.
‫Y ahora, solo para terminar,
‫ya que estamos hablando de código asincrónico aquí,
‫solo una última nota sobre las funciones de devolución de llamada.
‫Entonces, este modelo de devolución de llamada que acabamos
‫de discutir, donde se
‫llama a una función una vez que la anterior
‫ha terminado su trabajo, puede llevar rápidamente a un código difícil de leer e inmanejable.
‫Solo tome este ejemplo donde el segundo archivo
‫leído depende del primero,
‫luego, el tercer archivo leído depende del segundo
‫y, finalmente, queremos usar los datos finales
‫para escribir un archivo como resultado.
‫Eso parece bastante confuso, ¿verdad?
‫Quiero decir, va a funcionar
‫bien, pero es difícil razonar y
‫eso es solo con cuatro niveles de profundidad.
‫Imagina que tienes como 10 o 20 niveles,
‫que en realidad no es tan infrecuente.
‫De todos modos, esto es lo que llamamos el infierno de devolución de llamada.
‫Es un problema tan
‫común que ya tiene su propio nombre.
‫¿Y notas esta forma triangular aquí?
‫Esa es una señal muy clara de que estás en el infierno de las devoluciones de llamada.
‫Ahora, ¿cómo podemos escapar del infierno de devolución de llamada?
‫Bueno, podemos usar herramientas más avanzadas para
‫manejar código asincrónico, como ES6 promises
‫o incluso mejor, ES8 async / await.
‫Ahora, el modelo del que acabamos de
‫hablar seguirá siendo el mismo.
‫Simplemente tenemos formas más
‫elegantes de manejar el código en sí y escribirlo.
‫Y hay toda una sección opcional
‫más adelante en el curso sobre promesas y también, async / await, en
‫caso de que no esté familiarizado con ellas.
‫Pero por ahora, seguiremos usando devoluciones de
‫llamada porque eso es lo que Node usó
‫originalmente y fue diseñado alrededor.
‫Y ahora, dicho esto,
‫sigamos adelante y usemos este modelo asincrónico en
‫la práctica por primera vez.