{"id":752,"date":"2024-07-30T20:45:22","date_gmt":"2024-07-30T18:45:22","guid":{"rendered":"https:\/\/blog.sutilweb.eu\/?page_id=752"},"modified":"2024-07-30T20:45:23","modified_gmt":"2024-07-30T18:45:23","slug":"002-asincronia-y-el-event-loop","status":"publish","type":"page","link":"https:\/\/sutilweb.eu\/index.php\/lenguajes\/javascript\/javascript-practico\/08-programacion-asincrona\/002-asincronia-y-el-event-loop\/","title":{"rendered":"002. Asincron\u00eda y el Event Loop"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">La <strong>asincron\u00eda<\/strong> es uno de los pilares fundamentales de <strong>Javascript<\/strong>. <strong>Javascript<\/strong> es un lenguaje de un s\u00f3lo <strong>subproceso<\/strong> o <strong>hilo<\/strong>, lo que se conoce como <strong>Single thread<\/strong>, lo que significa que s\u00f3lo puede ejecutar una cosa a la vez.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Entender&nbsp; conceptos<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Es muy importante entender los siguientes conceptos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Procesamiento <strong>Single thread<\/strong> y <strong>Multi thread<\/strong>.<\/li>\n\n\n\n<li><strong>Operaciones de CPU<\/strong> y <strong>operaciones de I\/O<\/strong>.<\/li>\n\n\n\n<li><strong>Operaciones concurrentes<\/strong> y <strong>paralelas<\/strong>.<\/li>\n\n\n\n<li><strong>Operaciones bloqueantes<\/strong> y <strong>no bloqueantes<\/strong>.<\/li>\n\n\n\n<li><strong>Operaciones s\u00edncronas<\/strong> y <strong>as\u00edncronas<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Javascript<\/strong> es un lenguaje <strong>Single thread<\/strong>, y si bien los idiomas de un s\u00f3lo hilo simplifican la escritura de c\u00f3digo, ya que no hay que preocuparse por los problemas de <strong>concurrencia<\/strong>, como por ejm, el <strong>recolector de basura<\/strong> que existe en otros lenguajes de programaci\u00f3n. Esto tambi\u00e9n significa que no se pueden hacer operaciones largas como el acceso <strong>a la red<\/strong> sin que se bloquee el <strong>hilo principal<\/strong>. Es una de las principales preocupaciones en un lenguaje que trabaja en un s\u00f3lo hilo como es <strong>Javascript<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imaginemos que solicitamos datos a una <strong>API<\/strong>, dependiendo de la situaci\u00f3n de la red, del servidor&#8230; esto puede tardar mucho o poco tiempo en procesar dicha solicitud, y mientras, el hilo principal de nuestro c\u00f3digo se quedara bloqueado, y har\u00eda que la p\u00e1gina web no respondiera. Aqu\u00ed es donde entra en juego la <strong>asincron\u00eda<\/strong>, que se encarga de realizar largas solicitudes de red sin bloquear el hilo principal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Javascript<\/strong> es un lenguaje que fue dise\u00f1ado para ser ejecutado en navegadores, trabajar con peticiones hacia la red y procesar las interacciones con el usuario, y \u00e9sto al mismo tiempo de tratar de mantener una interfaz lo m\u00e1s fluida posible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Javascript<\/strong> trabaja bajo un <strong>modelo as\u00edncrono y no bloqueante<\/strong>, y tiene un <strong>loop de eventos<\/strong> (<strong>event loop<\/strong>) implementado de un s\u00f3lo hilo, lo que se conoce como <strong>Single thread<\/strong> para <strong>operaciones de entrada y salida<\/strong>. Gracias a ello es que <strong>Javascript<\/strong> es altamente <strong>concurrente<\/strong> a pesar de que sea un lenguaje de un s\u00f3lo hilo.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"574\" src=\"https:\/\/blog.sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop-1024x574.png\" alt=\"\" class=\"wp-image-755\" srcset=\"https:\/\/sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop-1024x574.png 1024w, https:\/\/sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop-300x168.png 300w, https:\/\/sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop-768x431.png 768w, https:\/\/sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop.png 1131w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Procesamiento Single thread y Multit hread<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Los <strong>hilos<\/strong> son las unidades b\u00e1sicas de ejecuci\u00f3n de cada proceso que realiza nuestra m\u00e1quina. Cada vez que abrimos nuestro navegador o nuestro editor de c\u00f3digo, en nuestra computadora se levanta un <strong>proceso<\/strong>, e internamente estos <strong>procesos<\/strong> pueden hacer correr varios <strong>hilos<\/strong> o un s\u00f3lo <strong>hilo<\/strong>, que es lo que ejecuta justamente su funcionalidad. Dependiendo de las caracter\u00edsticas del lenguaje, hay lenguajes que trabajan en un s\u00f3lo <strong>hilo<\/strong>, los denominados <strong>lenguajes Single thread<\/strong>, y lenguajes que trabajan en <strong>multi hilos<\/strong>, o <strong>lenguajes Multi thread<\/strong>. <strong>Javascript<\/strong> tiene un s\u00f3lo <strong>hilo de ejecuci\u00f3n<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La explicaci\u00f3n que se est\u00e1 dando sirve tanto para el ambiente de los navegadores como para el ambiente del servidor, v\u00eda <a href=\"https:\/\/nodejs.org\/es\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Node.js<\/strong><\/a>.&nbsp; <strong>Javascript<\/strong> tiene diferentes mecanismos para trabajar la <strong>asincron\u00eda<\/strong>, el primer mecanismo que tenemos son las funciones de tipo <strong>Callback<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hay un concepto denominado <strong>Call Stack<\/strong>, en el cual se van apilando las <strong>tareas<\/strong>, y dependiendo de sin son <strong>s\u00edncronas<\/strong> o <strong>as\u00edncronas<\/strong>, podemos ver como cada una de ellas se va liberando. <strong>Javascript<\/strong> trabaja bajo una filosof\u00eda denominada <strong>LIFO<\/strong> (<strong>Last In \/ First Out<\/strong>), que lo que significa es que la \u00faltima tarea en entrar es la primera en salir. Esta es la filosof\u00eda de la manera en como se van ejecutando las operaciones.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"422\" src=\"https:\/\/blog.sutilweb.eu\/wp-content\/uploads\/2024\/07\/Even-Loop-2.gif\" alt=\"\" class=\"wp-image-754\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Operaciones de CPU y operaciones de I\/O<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En un procesamiento, en el c\u00f3digo de la operaci\u00f3n podemos tener <strong>operaciones de CPU<\/strong>, o bien <strong>operaciones de entrada \/ salida<\/strong>. Las <strong>operaciones de CPU<\/strong> son las que pasan el mayor tiempo consumiendo los <strong>procesos<\/strong> de nuestra <strong>CPU<\/strong>. Por otro lado tenemos las <strong>operaciones de entrada y salida<\/strong> (<strong>I\/O<\/strong>) que son aquellas que pasan la mayor parte del tiempo esperando la petici\u00f3n del <strong>recurso<\/strong> que han solicitado (por ejm, enviar un formulario a que se procese en un servidor y nos env\u00ede la notificaci\u00f3n de que se ha enviado nuestra petici\u00f3n, cuando estamos haciendo un pago en linea, estamos esperando a que un <strong>API<\/strong> cobre y nos d\u00e9 el OK de todo correcto y hecho el pago, o cuando solicitamos datos a una <strong>API<\/strong> y nos devuelve los datos en formato <strong>JSON<\/strong>&#8230;).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En <strong>Javascript<\/strong> podemos ejecutar ambas, pero en la mayor\u00eda de los casos, por las caracter\u00edsticas del lenguaje, <strong>Javascript<\/strong> se va a comportar haciendo <strong>operaciones de entrada y salida<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Concurrencia y paralelismo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La <strong>concurrencia<\/strong> es cuando dos o m\u00e1s tareas progresan simult\u00e1neamente, es decir, se est\u00e1n ejecutando al mismo tiempo y avanzando simult\u00e1neamente, mientras que el <strong>paralelismo<\/strong> es cuando dos o m\u00e1s tareas se ejecutan al mismo tiempo. La <strong>concurrencia<\/strong> podr\u00eda parecer lo mismo, pero la clave est\u00e1 en la palabra <strong>progresar, <\/strong>algo es <strong>concurrente<\/strong> cuando diferentes tareas est\u00e1n progresando simult\u00e1neamente, es decir, al mismo tiempo, pero una pudo empezar antes y otra despu\u00e9s. Podemos tener <strong>concurrencias<\/strong> en un entorno <strong>s\u00edncrono<\/strong> y en un entorno <strong>as\u00edncrono<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Normalmente, <strong>Single thread<\/strong> est\u00e1 m\u00e1s relacionado a <strong>concurrencia,<\/strong> a <strong>no bloqueante<\/strong> y <strong>as\u00edncrono<\/strong>, pero, por ejm, <strong>Javascript<\/strong> es <strong>Single thread,<\/strong> y podemos tener operaciones <strong>s\u00edncronas<\/strong> y <strong>as\u00edncronas<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Operaciones bloqueantes y no bloqueantes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lo <strong>bloqueante<\/strong> y no <strong>bloqueante<\/strong> se refiere a la <strong>fase de espera<\/strong> (siempre que se est\u00e1 ejecutando nuestro c\u00f3digo hay una fase de espera). Una <strong>operaci\u00f3n bloqueante<\/strong> o <strong>no bloqueante<\/strong> se refiere a como toma esa <strong>fase de espera<\/strong>, una <strong>operaci\u00f3n bloqueante<\/strong> es aquella que no devuelve el control a la aplicaci\u00f3n hasta que haya terminado toda su tarea. Las <strong>operaciones no bloqueantes<\/strong> son aquellas que se ejecutan, y devuelven inmediatamente el control al <strong>hilo principal<\/strong>, no importando si han terminado o no la tarea, en el momento que una <strong>tarea no bloqueante<\/strong> se acabe mandar\u00e1 una notificaci\u00f3n y entonces se avisar\u00e1 al hilo principal.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Operaciones s\u00edncronas y as\u00edncronas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lo <strong>s\u00edncrono<\/strong> y <strong>as\u00edncrono<\/strong> se refiere a cuando tendr\u00e1 lugar la respuesta. Pensando en el presente, pasado y futuro, <strong>s\u00edncrono<\/strong> significa que la respuesta sucede en el presente, es decir, en el tiempo inmediato, una <strong>operaci\u00f3n<\/strong> <strong>s\u00edncrona<\/strong> espera el resultado. Una <strong>operaci\u00f3n<\/strong> <strong>as\u00edncrona<\/strong>, la respuesta sucede en un futuro, es decir, se ejecuta, pero no sabe cuando va a venir la respuesta. La <strong>operaci\u00f3n as\u00edncrona<\/strong> no va a esperar el resultado, es por ello que suelta inmediatamente el control y se lo devuelve al <strong>hilo principal<\/strong>, por eso es que generalmente se suelen asociar los conceptos de <strong>bloqueante<\/strong> con <strong>s\u00edncrono<\/strong>, y <strong>no bloqueante<\/strong> con <strong>as\u00edncrono<\/strong>, pero incluso puede existir c\u00f3digo <strong>s\u00edncrono bloqueante<\/strong> y <strong>no bloqueante<\/strong>. El <strong>c\u00f3digo as\u00edncrono<\/strong>, pr\u00e1cticamente siempre va a ser <strong>no bloqueante<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dos tipos de c\u00f3digo en Javascript<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En <strong>Javascript<\/strong> vamos a tener dos tipos de c\u00f3digo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>C\u00f3digo s\u00edncrono bloqueante<\/strong>.<\/li>\n\n\n\n<li><strong>C\u00f3digo as\u00edncrono no bloqueante<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Existe una herramienta que nos permite ver como va fluyendo todo el c\u00f3digo, se llama <a href=\"http:\/\/latentflip.com\/loupe\/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Loupe<\/strong><\/a>. Esta herramienta lo que permite es ver de una manera visual como se van llenando las operaciones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Ejm de c\u00f3digo s\u00edncrono y as\u00edncrono<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  &nbsp; &nbsp; \/\/ Ejm de c\u00f3digo s\u00edncrono bloqueante\n&nbsp; &nbsp; &nbsp; (() =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"C\u00f3digo s\u00edncrono\");\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Inicio\");\n&nbsp; &nbsp; &nbsp; &nbsp; function dos() {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Dos\");\n&nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; function uno() {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Uno\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dos();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Tres\");\n&nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; uno();\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Fin\");\n&nbsp; &nbsp; &nbsp; })();\n\n&nbsp; &nbsp; &nbsp; \/\/ Ejm de c\u00f3digo as\u00edncrono no bloqueante\n&nbsp; &nbsp; &nbsp; (() =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"C\u00f3digo as\u00edncrono\");\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Inicio\");\n&nbsp; &nbsp; &nbsp; &nbsp; function dos() {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(function () {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Dos\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 1000);\n&nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; function uno() {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(function () {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Uno\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 0);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dos();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Tres\");\n&nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; uno();\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Fin\");\n&nbsp; &nbsp; &nbsp; })();<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">En el segundo caso, al envolver las funciones en una funci\u00f3n <strong><em>setTimeout()<\/em><\/strong>, hace que se pase a la <strong>pila de tareas<\/strong>, por lo que lo primero que se ejecuta es el <strong>c\u00f3digo as\u00edncrono bloqueante<\/strong>, y posteriormente el <strong>as\u00edncrono no bloqueante<\/strong>, es decir, el c\u00f3digo dentro de un <strong><em>setTimeout()<\/em><\/strong>. Los <strong><em>console.log()<\/em><\/strong> tienen mayor preferencia a la hora de ejecutarse que las funciones <strong><em>setTimeout()<\/em><\/strong>, por ello se ejecutan antes, ya que el <strong><em>setTimeout()<\/em><\/strong> depende de un tiempo, aunque sea cero.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">En resumen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En resumen, <strong>Javascript<\/strong> usa un <strong>modelo as\u00edncrono<\/strong> <strong>y no bloqueante<\/strong> con un <strong>loop de eventos<\/strong> implementado en un <strong>s\u00f3lo hilo<\/strong> (<strong>Single thread<\/strong>) para <strong>operaciones de entrada y salida<\/strong> (<strong>input\/otuput<\/strong>). En los pr\u00f3ximos cap\u00edtulos veremos que <strong>Javascript<\/strong> tiene diferentes mecanismos para trabajar las <strong>sincron\u00edas<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La asincron\u00eda es uno de los pilares fundamentales de Javascript. Javascript es un lenguaje de un s\u00f3lo subproceso o hilo, lo que&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":746,"menu_order":1,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-752","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Sutil Web","author_link":"https:\/\/sutilweb.eu\/index.php\/author\/sutilweb\/"},"uagb_comment_info":0,"uagb_excerpt":"La asincron\u00eda es uno de los pilares fundamentales de Javascript. Javascript es un lenguaje de un s\u00f3lo subproceso o hilo, lo que...","_links":{"self":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/752","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/comments?post=752"}],"version-history":[{"count":2,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/752\/revisions"}],"predecessor-version":[{"id":756,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/752\/revisions\/756"}],"up":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/746"}],"wp:attachment":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/media?parent=752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}