javascript - noticias - node js tutorial
¿Por qué node.js es asincrónico? (3)
Nadie ha preguntado esto (de todas las ''sugerencias'' que recibo y también de buscar antes de preguntar aquí).
Entonces, ¿por qué node.js es asíncrono?
De lo que he deducido después de algunas investigaciones:
Los lenguajes como PHP y Python son lenguajes de scripting (podría estar equivocado sobre los lenguajes reales que son lenguajes de scripting) mientras que JavaScript no lo es. (Supongo que esto se deriva del hecho de que JS no compila?)
Node.js se ejecuta en un único hilo, mientras que los lenguajes de script utilizan varios hilos.
Asincrónico significa sin estado y que la conexión es persistente mientras que sincrónico es el (casi) opuesto.
Tal vez la respuesta se encuentre en algún lugar indicado anteriormente, pero todavía no estoy seguro.
Mi segunda y última pregunta relacionada con este tema es esta:
¿Podría JavaScript convertirse en un lenguaje síncrono?
PD. Sé que algunos de ustedes preguntarán "¿por qué querrían hacer JS sincrónico?" en tus respuestas, pero la verdad es que yo no. Solo estoy haciendo este tipo de preguntas porque estoy seguro de que hay más personas que yo que han pensado en esas preguntas.
¿Podría JavaScript convertirse en un lenguaje síncrono?
Javascript no es un "lenguaje asincrónico"; más bien, node.js tiene muchas API asíncronas. La asincronía es una propiedad de la API y no del idioma. La facilidad con la que las funciones se pueden crear y pasar en javascript hace que sea conveniente pasar funciones de devolución de llamada, que es una forma de manejar el flujo de control en una API asíncrona, pero no hay nada inherentemente asíncrono sobre javascript . Javascript puede admitir fácilmente API síncronas.
¿Por qué node.js es asincrónico?
Node.js favorece las API asíncronas porque es de subproceso único. Esto le permite administrar de manera eficiente sus propios recursos, pero requiere que las operaciones de larga ejecución no sean de bloqueo, y las API asíncronas son una forma de permitir el control del flujo con muchas operaciones sin bloqueo.
Node.js se ejecuta en un único hilo, mientras que los lenguajes de script utilizan varios hilos.
No técnicamente. Node.js usa varios hilos, pero solo un hilo de ejecución. Los hilos de fondo son para tratar con IO para hacer que todas las bondades asincrónicas funcionen. Tratar con los hilos de manera eficiente es una molestia real, por lo que la siguiente mejor opción es ejecutar un bucle de eventos para que el código pueda ejecutarse mientras los hilos de fondo están bloqueados en IO.
Asincrónico significa sin estado y que la conexión es persistente mientras que sincrónico es el (casi) opuesto.
No necesariamente. Puede conservar el estado en un sistema asíncrono con bastante facilidad. Por ejemplo, en Javascript, puede usar bind()
para vincular this
a una función, conservando así el estado explícitamente cuando la función retorna:
function State() {
// make sure that whenever doStuff is called it maintains its state
this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};
Asíncrono significa no esperar a que finalice una operación, sino registrar un oyente en su lugar. Esto ocurre todo el tiempo en otros idiomas, especialmente en cualquier cosa que necesite aceptar la entrada del usuario. Por ejemplo, en una GUI de Java, no bloquea la espera de que el usuario presione un botón, pero registra un oyente con la GUI.
Mi segunda y última pregunta relacionada con este tema es esta:
¿Podría JavaScript convertirse en un lenguaje síncrono?
Técnicamente, todos los idiomas son sincrónicos, incluso Javascript. Sin embargo, Javascript funciona mucho mejor en un diseño asincrónico porque fue diseñado para ser de un solo hilo.
Básicamente hay dos tipos de programas:
- Límite de CPU: la única forma de hacerlo más rápido es obtener más tiempo de CPU
- IO bound: pasa mucho tiempo esperando datos, por lo que un procesador más rápido no importará
Los videojuegos, los procesadores numéricos y los compiladores están vinculados a la CPU, mientras que los servidores web y las GUI generalmente están vinculados a IO. Javascript es relativamente lento (debido a lo complejo que es), por lo que no podría competir en un escenario vinculado a la CPU (confía en mí, he escrito mi parte justa de Javascript para CPU).
En lugar de codificar en términos de clases y objetos, Javascript se presta a la codificación en términos de funciones simples que pueden encadenarse. Esto funciona muy bien en el diseño asincrónico, ya que los algoritmos se pueden escribir para procesar los datos de forma gradual a medida que entran. IO (especialmente IO de red) es muy lento, por lo que hay bastante tiempo entre los paquetes de datos.
Ejemplo
Supongamos que tiene 1000 conexiones en vivo, cada una entregando un paquete cada milisegundo, y procesar cada paquete lleva 1 microsegundo (muy razonable). Supongamos también que cada conexión envía 5 paquetes.
En una aplicación síncrona de subproceso único, cada conexión se manejará en serie. El tiempo total empleado es (5 * 1 + 5 * .001) * 1000 milisegundos, o ~ 5005 milisegundos.
En una aplicación asíncrona de subproceso único, cada conexión se manejará en paralelo. Como cada paquete tarda 1 milisegundo, y el procesamiento de cada paquete demora .001 milisegundos, podemos procesar cada paquete de conexión entre paquetes, por lo que nuestra fórmula se convierte en: 1000 * .001 + 5 * 1 milisegundos, o ~ 6 milisegundos.
La solución tradicional a este problema fue crear más hilos. Esto solucionó el problema de IO, pero luego cuando aumentó el número de conexiones, también lo hizo el uso de memoria (los subprocesos cuestan mucha memoria) y el uso de CPU (la multiplexación de 100 subprocesos en 1 núcleo es más dura que 1 subproceso en 1 núcleo).
Sin embargo, hay desventajas. Si su aplicación web también necesita hacer un gran número de crujidos, usted es SOL porque mientras está procesando números, las conexiones deben esperar. Threading resuelve esto porque el sistema operativo puede intercambiar su tarea intensiva de CPU cuando los datos están listos para un subproceso que espera en IO. Además, node.js está vinculado a un único núcleo, por lo que no puede aprovechar su procesador multi-core a menos que genere múltiples instancias y solicitudes de proxy.
Javascript no se compila en nada. Se "evalúa" en tiempo de ejecución, al igual que PHP y Ruby. Por lo tanto, es un lenguaje de scripting como PHP / Ruby. (su nombre oficial es en realidad ECMAScript).
El ''modelo'' al que se adhiere Node es un poco diferente que PHP / Ruby. Node.js usa un ''bucle de evento'' (el único hilo) que tiene el objetivo de tomar solicitudes de red y manejarlas muy rápidamente, y si por alguna razón encuentra una operación que lleva un tiempo (solicitud de API, consulta de base de datos - básicamente cualquier cosa que implique IO (entrada / salida)) lo pasa a un hilo de ''trabajador'' de fondo y se apaga para hacer otra cosa mientras el hilo de trabajo espera a que se complete la tarea larga. Cuando eso suceda, el ''ciclo de eventos'' principal tomará los resultados y continuará con ellos.
PHP / Ruby siguiendo un modelo de subprocesamiento. Esencialmente, para cada solicitud de red entrante, el servidor de aplicaciones genera un hilo o proceso isloated para manejar la solicitud. Esto no escala tremendamente bien y el enfoque de Node se cita como uno de sus puntos fuertes en comparación con este modelo.
Asincrónico significa sin estado y que la conexión es persistente mientras que sincrónico es el (casi) opuesto.
No. Las instrucciones sincrónicas se completan en un orden natural, del primero al último. Las instrucciones asíncronas significan que si un paso en el flujo de un programa lleva un tiempo relativamente largo, el programa continuará ejecutando operaciones y simplemente regresará a esta operación cuando se complete.
¿Podría JavaScript convertirse en un lenguaje síncrono?
Algunas operaciones en JavaScript son sincrónicas. Otros son asincrónicos. Por ejemplo:
Operaciones de bloqueo:
for(var k = 0; k < 1; k = k - 1;){
alert(''this will quickly get annoying and the loop will block execution'')
alert(''this is blocked and will never happen because the above loop is infinite'');
Asincrónico:
jQuery.get(''/foo'', function (result) { alert(''This will occur 2nd, asynchronously''); });
alert(''This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.'');