{"id":16678,"date":"2025-01-25T22:51:24","date_gmt":"2025-01-25T19:21:24","guid":{"rendered":"https:\/\/www.itpiran.net\/blog\/?p=16678"},"modified":"2025-01-25T22:51:24","modified_gmt":"2025-01-25T19:21:24","slug":"understanding-the-event-loop-callbacks","status":"publish","type":"post","link":"https:\/\/www.itpiran.net\/blog\/es\/tutorials\/understanding-the-event-loop-callbacks\/","title":{"rendered":"Comprender el bucle de eventos y las devoluciones de llamada"},"content":{"rendered":"<h2 id=\"%d9%85%d9%82%d8%af%d9%85%d9%87\">Introducci\u00f3n<\/h2>\n<p>En los inicios de Internet, los sitios web sol\u00edan consistir en datos est\u00e1ticos en una p\u00e1gina HTML. Pero ahora que las aplicaciones web se han vuelto m\u00e1s interactivas y din\u00e1micas, se ha vuelto cada vez m\u00e1s necesario realizar operaciones intensivas, como solicitudes de red externas para recuperar datos de la API. Para realizar estas operaciones en JavaScript, un desarrollador debe utilizar t\u00e9cnicas de programaci\u00f3n as\u00edncrona.<\/p>\n<p>Dado que JavaScript es un lenguaje de programaci\u00f3n de un solo subproceso con un modelo de ejecuci\u00f3n concurrente que procesa las operaciones una tras otra, solo puede procesar un comando a la vez. Sin embargo, una acci\u00f3n como solicitar datos de una API puede tardar un tiempo indeterminado, dependiendo del tama\u00f1o de los datos solicitados, la velocidad de la conexi\u00f3n de red y otros factores. Si las llamadas a la API se realizaran sincr\u00f3nicamente, el navegador no podr\u00eda procesar ninguna entrada del usuario, como desplazarse o hacer clic en un bot\u00f3n, hasta que se complete la operaci\u00f3n. Esto se conoce como bloqueo.<\/p>\n<p>Para evitar comportamientos de bloqueo, el entorno del navegador cuenta con numerosas API web asincr\u00f3nicas a las que JavaScript puede acceder, lo que significa que pueden ejecutarse en paralelo con otras operaciones en lugar de secuencialmente. Esto resulta \u00fatil porque permite al usuario seguir usando el navegador con normalidad mientras se procesa la operaci\u00f3n asincr\u00f3nica.<\/p>\n<h2 id=\"%d8%ad%d9%84%d9%82%d9%87-%d8%b1%d9%88%db%8c%d8%af%d8%a7%d8%af\">Bucle de eventos<\/h2>\n<p>Esta secci\u00f3n explica c\u00f3mo JavaScript gestiona el c\u00f3digo as\u00edncrono con el bucle de eventos. Primero, se muestra una demostraci\u00f3n del bucle de eventos en funcionamiento y, a continuaci\u00f3n, se explican dos elementos del bucle: la pila y la cola.<\/p>\n<p>El c\u00f3digo JavaScript que no utiliza ninguna API web as\u00edncrona se ejecuta sincr\u00f3nicamente, una a la vez, secuencialmente. Esto se ilustra con este c\u00f3digo de ejemplo, que llama a tres funciones, cada una de las cuales imprime un n\u00famero en la consola:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Define three example functions\r\nfunction first() {\r\nconsole.log(1)\r\n}\r\n\r\nfunction second() {\r\nconsole.log(2)\r\n}\r\n\r\nfunction third() {\r\nconsole.log(3)\r\n}<\/code><\/pre>\n<\/div>\n<p>En este c\u00f3digo, define tres funciones que imprimen n\u00fameros usando console.log().<\/p>\n<p>Luego, escribe las llamadas a las funciones:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Execute the functions\r\nfirst()\r\nsecond()\r\nthird()<\/code><\/pre>\n<\/div>\n<p>La salida se basar\u00e1 en el orden en que se llaman las funciones: primero(), segundo() y luego tres():<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>Output\r\n1\r\n2\r\n3<\/code><\/pre>\n<\/div>\n<p>Al usar una API web as\u00edncrona, las reglas se complican. Una API integrada con la que puedes experimentar es setTimeout, que establece un temporizador y realiza una acci\u00f3n tras un tiempo especificado. setTimeout debe ser as\u00edncrono; de lo contrario, el navegador se bloquear\u00e1 mientras esperas, lo que resultar\u00e1 en una mala experiencia de usuario.<\/p>\n<p>Para simular una solicitud asincr\u00f3nica, agregue setTimeout a la segunda funci\u00f3n:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Define three example functions, but one of them contains asynchronous code\r\nfunction first() {\r\nconsole.log(1)\r\n}\r\n\r\nfunction second() {\r\nsetTimeout(() =&gt; {\r\nconsole.log(2)\r\n}, 0)\r\n}\r\n\r\nfunction third() {\r\nconsole.log(3)\r\n}<\/code><\/pre>\n<\/div>\n<p>setTimeout acepta dos argumentos: una funci\u00f3n que se ejecuta asincr\u00f3nicamente y el tiempo de espera antes de llamar a dicha funci\u00f3n. En este c\u00f3digo, se coloca console.log en una funci\u00f3n an\u00f3nima y se pasa a setTimeout. Luego, se configura la funci\u00f3n para que se ejecute despu\u00e9s de 0 milisegundos.<\/p>\n<p>Ahora llama a las funciones como antes:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Execute the functions\r\nfirst()\r\nsecond()\r\nthird()<\/code><\/pre>\n<\/div>\n<p>Se podr\u00eda esperar que, al establecer setTimeout en 0, la ejecuci\u00f3n de estas tres funciones imprimiera los n\u00fameros en orden secuencial. Sin embargo, al ser as\u00edncrona, la funci\u00f3n imprimir\u00e1 con un salto de l\u00ednea en el \u00faltimo:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>Output\r\n1\r\n3\r\n2<\/code><\/pre>\n<\/div>\n<p>No importa si configura el temporizador a cero segundos o a cinco minutos: console.log, llamado por c\u00f3digo as\u00edncrono, se ejecutar\u00e1 despu\u00e9s de las funciones s\u00edncronas de nivel superior. Esto se debe a que el entorno host de JavaScript (en este caso, el navegador) utiliza un bucle de eventos para gestionar eventos concurrentes o paralelos. Dado que JavaScript solo puede ejecutar un comando a la vez, necesita el bucle de eventos para saber cu\u00e1ndo se ejecuta un comando en particular. El bucle de eventos gestiona esto mediante los conceptos de pilas y colas.<\/p>\n<h5 id=\"%d9%be%d8%b4%d8%aa%d9%87\">Pila<\/h5>\n<p>La pila, o pila de llamadas, contiene el estado de la funci\u00f3n que se est\u00e1 ejecutando. Si no est\u00e1 familiarizado con el concepto de pila, puede imaginarla como un array con propiedades LIFO (\u00faltimo en entrar, primero en salir), lo que significa que solo puede agregar o eliminar elementos de la parte inferior de la pila. JavaScript ejecuta el fotograma actual (o la llamada a la funci\u00f3n en un entorno espec\u00edfico) en la pila, luego lo elimina y pasa al siguiente fotograma.<\/p>\n<p>Para un ejemplo que contiene solo c\u00f3digo sincr\u00f3nico, el navegador se ejecuta en el siguiente orden:<\/p>\n<ul>\n<li><strong>primero()<\/strong> Agregue a la pila, ejecute first() que registra 1 en la consola, elimine first() de la pila.<\/li>\n<li><strong>segundo()<\/strong> Agregue a la pila, ejecute second() que imprime 2 en la consola, elimine second() de la pila.<\/li>\n<li><strong>tercero ()<\/strong> Agregue a la pila, ejecute third() que registra 3 en la consola, elimine third() de la pila.<\/li>\n<\/ul>\n<p>El segundo ejemplo con setTimout es el siguiente:<\/p>\n<ul>\n<li><strong>primero()<\/strong> Agregue a la pila, ejecute first() que registra 1 en la consola, elimine first() de la pila.<\/li>\n<li><strong>segundo()<\/strong> Agregue a la pila, ejecute second().\n<ul>\n<li>Agregue setTimeout() a la pila, ejecute la API web setTimeout() que inicia el temporizador y agrega la funci\u00f3n an\u00f3nima a la cola, elimine setTimeout() de la pila.<\/li>\n<\/ul>\n<\/li>\n<li><strong>segundo()<\/strong> Retirar de la pila.<\/li>\n<li><strong>Tercero ()<\/strong> Agregue a la pila, ejecute third() que registra 3 en la consola, elimine third() de la pila.<\/li>\n<li>El bucle de eventos verifica la cola en busca de mensajes pendientes y encuentra la funci\u00f3n an\u00f3nima de setTimeout(), agrega la funci\u00f3n a la pila que registra 2 en la consola y luego la elimina de la pila.<\/li>\n<\/ul>\n<p>Al utilizar setTimeout, una API web asincr\u00f3nica, se introduce el concepto de cola, que este tutorial cubrir\u00e1 m\u00e1s adelante.<\/p>\n<h5 id=\"%d8%b5%d9%81\">Cola<\/h5>\n<p>Una cola, tambi\u00e9n llamada cola de mensajes o cola de tareas, es un \u00e1rea de espera para funciones. Cuando la pila de llamadas est\u00e1 vac\u00eda, el bucle de eventos revisa la cola en busca de mensajes pendientes, empezando por el m\u00e1s antiguo. Al encontrar uno, lo a\u00f1ade a la pila, que ejecuta la funci\u00f3n contenida en el mensaje.<\/p>\n<p>En el ejemplo setTimeout, la funci\u00f3n an\u00f3nima se ejecuta inmediatamente despu\u00e9s del resto de la ejecuci\u00f3n de nivel superior, ya que el temporizador se configur\u00f3 en 0 segundos. Es importante recordar que el temporizador no implica que el c\u00f3digo se ejecutar\u00e1 exactamente a los 0 segundos ni en un momento espec\u00edfico, sino que a\u00f1adir\u00e1 la funci\u00f3n an\u00f3nima a la cola durante ese tiempo. Este sistema de colas existe porque si el temporizador a\u00f1adiera la funci\u00f3n an\u00f3nima directamente a la pila despu\u00e9s de que expire, interrumpir\u00eda la funci\u00f3n que se est\u00e1 ejecutando, lo que podr\u00eda tener efectos impredecibles.<\/p>\n<p><span style=\"color: #ff0000;\">Nota: Tambi\u00e9n existe otra cola llamada cola de trabajos o cola de microtareas que gestiona promesas. Las microtareas, como las promesas, se ejecutan con mayor prioridad que las macrotareas como setTimeout.<\/span><\/p>\n<p><span style=\"color: #000000;\">Ahora que sabes c\u00f3mo el bucle de eventos usa la pila y la cola para gestionar el orden de ejecuci\u00f3n del c\u00f3digo, el siguiente paso es descubrir c\u00f3mo controlar dicho orden. Para ello, primero aprender\u00e1s la principal forma de garantizar que el bucle de eventos gestione correctamente el c\u00f3digo as\u00edncrono: las funciones de devoluci\u00f3n de llamada.<\/span><\/p>\n<h2 id=\"callback-functions\">Funciones de devoluci\u00f3n de llamada<\/h2>\n<p>En el ejemplo setTimeout, la funci\u00f3n con el tiempo de espera se ejecuta despu\u00e9s de todo en el contexto principal de la ejecuci\u00f3n de nivel superior. Sin embargo, si desea asegurarse de que una de las funciones, como la tercera, se ejecute despu\u00e9s del tiempo de espera, debe usar t\u00e9cnicas de codificaci\u00f3n as\u00edncrona. El tiempo de espera puede representar una llamada API as\u00edncrona que contiene datos. Si desea trabajar con los datos de la llamada API, primero debe asegurarse de que se devuelvan.<\/p>\n<p>La principal soluci\u00f3n a este problema es usar funciones de devoluci\u00f3n de llamada. Estas funciones no tienen una sintaxis especial. Son simplemente una funci\u00f3n que se pasa como argumento a otra funci\u00f3n. Una funci\u00f3n que toma otra funci\u00f3n como argumento se denomina funci\u00f3n de orden superior. Seg\u00fan esta definici\u00f3n, cualquier funci\u00f3n puede convertirse en una funci\u00f3n llamada si se pasa como argumento. Las llamadas telef\u00f3nicas no son inherentemente as\u00edncronas, pero pueden utilizarse con fines as\u00edncronos.<\/p>\n<p>A continuaci\u00f3n se muestra un ejemplo de c\u00f3digo de sintaxis de una funci\u00f3n de orden superior y una devoluci\u00f3n de llamada:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ A function\r\nfunction fn() {\r\nconsole.log('Just a function')\r\n}\r\n\r\n\/\/ A function that takes another function as an argument\r\nfunction higherOrderFunction(callback) {\r\n\/\/ When you call a function that is passed as an argument, it is referred to as a callback\r\ncallback()\r\n}\r\n\r\n\/\/ Passing a function\r\nhigherOrderFunction(fn)<\/code><\/pre>\n<\/div>\n<p>En este c\u00f3digo, define una funci\u00f3n fn, define una funci\u00f3n aboveOrderFunction que toma una funci\u00f3n de devoluci\u00f3n de llamada como argumento y pasa fn como una devoluci\u00f3n de llamada a aboveOrderFunction.<\/p>\n<p>Al ejecutar este c\u00f3digo se lograr\u00e1 lo siguiente:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-plain\" data-lang=\"Plain Text\"><code>Output\r\nJust a function<\/code><\/pre>\n<\/div>\n<p>Volvamos a la primera, segunda y tercera funci\u00f3n con setTimeout. Esto es lo que tienes hasta ahora:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>function first() {\r\nconsole.log(1)\r\n}\r\n\r\nfunction second() {\r\nsetTimeout(() =&gt; {\r\nconsole.log(2)\r\n}, 0)\r\n}\r\n\r\nfunction third() {\r\nconsole.log(3)\r\n}<\/code><\/pre>\n<\/div>\n<p>La tarea consiste en que la tercera funci\u00f3n retrase siempre la ejecuci\u00f3n hasta que se complete la acci\u00f3n asincr\u00f3nica de la segunda funci\u00f3n. Aqu\u00ed es donde entran en juego las devoluciones de llamada. En lugar de ejecutar la primera, la segunda y la tercera en el nivel superior de ejecuci\u00f3n, se pasa la tercera funci\u00f3n como argumento a la segunda. Esta \u00faltima ejecuta la devoluci\u00f3n de llamada una vez completada la acci\u00f3n asincr\u00f3nica.<\/p>\n<p>Aqu\u00ed hay tres funciones implementadas con una devoluci\u00f3n de llamada:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Define three functions\r\nfunction first() {\r\nconsole.log(1)\r\n}\r\n\r\nfunction second(callback) {\r\nsetTimeout(() =&gt; {\r\nconsole.log(2)\r\n\r\n\/\/ Execute the callback function\r\ncallback()\r\n}, 0)\r\n}\r\n\r\nfunction third() {\r\nconsole.log(3)\r\n}<\/code><\/pre>\n<\/div>\n<p>Ahora ejecute el primero y el segundo, luego pase el tercero como argumento al segundo:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>first()\r\nsecond(third)<\/code><\/pre>\n<\/div>\n<p>Despu\u00e9s de ejecutar este bloque de c\u00f3digo, obtendr\u00e1 el siguiente resultado:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-plain\" data-lang=\"Plain Text\"><code>Output\r\n1\r\n2\r\n3<\/code><\/pre>\n<\/div>\n<p>Primero se imprime 1 y, una vez que expira el temporizador (en este caso es cero segundos, pero puede cambiarlo a cualquier valor), se imprime 2 y luego 3. Trabaje hasta que se complete la API web asincr\u00f3nica (setTimeout).<\/p>\n<p>El punto clave es que las funciones de devoluci\u00f3n de llamada no son as\u00edncronas: setTimeout es una API web as\u00edncrona responsable de gestionar tareas as\u00edncronas. Las devoluciones de llamada solo permiten recibir notificaciones cuando una tarea as\u00edncrona se completa y gestionar su \u00e9xito o fracaso.<\/p>\n<p>Ahora que ha aprendido a usar devoluciones de llamadas para realizar tareas asincr\u00f3nicas, la siguiente secci\u00f3n explica los problemas asociados con la anidaci\u00f3n de demasiadas llamadas y la creaci\u00f3n de una &quot;pir\u00e1mide de la perdici\u00f3n&quot;.<\/p>\n<h2 id=\"callback-%d8%aa%d9%88-%d8%af%d8%b1-%d8%aa%d9%88-%d9%88-%d9%87%d8%b1%d9%85-%d8%b9%d8%b0%d8%a7%d8%a8\">Devoluci\u00f3n de llamada anidada y Pir\u00e1mide de la perdici\u00f3n<\/h2>\n<p>Las funciones de devoluci\u00f3n de llamada son una forma eficaz de garantizar que una funci\u00f3n se retrase hasta que otra se complete y retorne con datos. Sin embargo, debido a la naturaleza anidada de las devoluciones de llamada, el c\u00f3digo puede saturarse si se tienen muchas solicitudes as\u00edncronas consecutivas que dependen unas de otras. Esto supon\u00eda una gran frustraci\u00f3n para los primeros desarrolladores de JavaScript, y como resultado, el c\u00f3digo que contiene llamadas anidadas suele denominarse la &quot;pir\u00e1mide del tormento&quot; o el &quot;infierno de las devoluciones de llamada&quot;.<\/p>\n<p>A continuaci\u00f3n se muestra una demostraci\u00f3n de devoluciones de llamadas anidadas:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>function pyramidOfDoom() {\r\nsetTimeout(() =&gt; {\r\nconsole.log(1)\r\nsetTimeout(() =&gt; {\r\nconsole.log(2)\r\nsetTimeout(() =&gt; {\r\nconsole.log(3)\r\n}, 500)\r\n}, 2000)\r\n}, 1000)\r\n}<\/code><\/pre>\n<\/div>\n<p>En este c\u00f3digo, cada nuevo setTimeout se coloca dentro de una funci\u00f3n de orden superior, creando una pir\u00e1mide de llamadas cada vez m\u00e1s profundas. Al ejecutar este c\u00f3digo, se obtendr\u00e1 el siguiente resultado:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-plain\" data-lang=\"Plain Text\"><code>Output\r\n1\r\n2\r\n3<\/code><\/pre>\n<\/div>\n<p>En la pr\u00e1ctica, con c\u00f3digo as\u00edncrono real, esto puede complicarse mucho m\u00e1s. Probablemente necesitar\u00e1 gestionar errores en c\u00f3digo as\u00edncrono y luego pasar datos de cada respuesta a la siguiente solicitud. Hacer esto con devoluciones de llamada dificulta la lectura y el mantenimiento del c\u00f3digo.<\/p>\n<p>He aqu\u00ed un ejemplo pr\u00e1ctico de una \u201cpir\u00e1mide de la perdici\u00f3n\u201d m\u00e1s realista con la que puedes jugar:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>\/\/ Example asynchronous function\r\nfunction asynchronousRequest(args, callback) {\r\n\/\/ Throw an error if no arguments are passed\r\nif (!args) {\r\nreturn callback(new Error('Whoa! Something went wrong.'))\r\n} else {\r\nreturn setTimeout(\r\n\/\/ Just adding in a random number so it seems like the contrived asynchronous function\r\n\/\/ returned different data\r\n() =&gt; callback(null, {body: args + ' ' + Math.floor(Math.random() * 10)}),\r\n500,\r\n)\r\n}\r\n}\r\n\/\/ Nested asynchronous requests\r\nfunction callbackHell() {\r\nasynchronousRequest('First', function first(error, response) {\r\nif (error) {\r\nconsole.log(error)\r\nreturn\r\n}\r\nconsole.log(response.body)\r\nasynchronousRequest('Second', function second(error, response) {\r\nif (error) {\r\nconsole.log(error)\r\nreturn\r\n}\r\nconsole.log(response.body)\r\nasynchronousRequest(null, function third(error, response) {\r\nif (error) {\r\nconsole.log(error)\r\nreturn\r\n}\r\nconsole.log(response.body)\r\n})\r\n})\r\n})\r\n}\r\n\/\/ Execute \r\ncallbackHell()<\/code><\/pre>\n<\/div>\n<p>En este c\u00f3digo, debes tener en cuenta cada funci\u00f3n para una posible respuesta y un posible error, lo que hace que la funci\u00f3n callbackHell sea visualmente confusa.<\/p>\n<p>Al ejecutar este c\u00f3digo obtendr\u00e1 el siguiente resultado:<\/p>\n<div class=\"hcb_wrap\" data-no-translation=\"\" data-no-auto-translation=\"\">\n<pre class=\"prism line-numbers lang-plain\" data-lang=\"Plain Text\"><code>Output\r\nFirst 9\r\nSecond 3\r\nError: Whoa! Something went wrong.\r\nat asynchronousRequest (&lt;anonymous&gt;:4:21)\r\nat second (&lt;anonymous&gt;:29:7)\r\nat &lt;anonymous&gt;:9:13<\/code><\/pre>\n<\/div>\n<h2 id=\"%d9%86%d8%aa%db%8c%d8%ac%d9%87\">Resultado<\/h2>\n<p>Este m\u00e9todo de gesti\u00f3n de c\u00f3digo as\u00edncrono es complejo. Por ello, en ES6 se introdujo el concepto de promesas. Este es el tema central de la siguiente secci\u00f3n.<\/p>","protected":false},"excerpt":{"rendered":"Introducci\u00f3n En los inicios de Internet, los sitios web sol\u00edan consistir en datos est\u00e1ticos en una p\u00e1gina HTML\u2026","protected":false},"author":1,"featured_media":16684,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_yoast_wpseo_focuskw":"\u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks","_yoast_wpseo_title":"","_yoast_wpseo_metadesc":"","_yoast_wpseo_canonical":"","_yoast_wpseo_opengraph-description":"","_yoast_wpseo_opengraph-image":"","_yoast_wpseo_twitter-description":"","_yoast_wpseo_twitter-image":"","_yoast_wpseo_focuskeywords":"[]","_yoast_wpseo_primary_category":"193","footnotes":""},"categories":[193,363],"tags":[384],"class_list":{"0":"post-16678","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-tutorials","8":"category-programming","9":"tag-java-script"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks - \u0628\u0644\u0627\u06af ITPiran<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.itpiran.net\/blog\/es\/tutorials\/understanding-the-event-loop-callbacks\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks - \u0628\u0644\u0627\u06af ITPiran\" \/>\n<meta property=\"og:description\" content=\"\u0645\u0642\u062f\u0645\u0647 \u062f\u0631 \u0631\u0648\u0632\u0647\u0627\u06cc \u0627\u0648\u0644\u06cc\u0647 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u0648\u0628 \u0633\u0627\u06cc\u062a \u0647\u0627 \u0627\u063a\u0644\u0628 \u0627\u0632 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u062b\u0627\u0628\u062a \u062f\u0631 \u06cc\u06a9 \u0635\u0641\u062d\u0647 HTML \u062a\u0634\u06a9\u06cc\u0644&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.itpiran.net\/blog\/es\/tutorials\/understanding-the-event-loop-callbacks\/\" \/>\n<meta property=\"og:site_name\" content=\"\u0628\u0644\u0627\u06af ITPiran\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-25T19:21:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1793\" \/>\n\t<meta property=\"og:image:height\" content=\"1110\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#\\\/schema\\\/person\\\/04ed27b919baca468a2273f8e4318f81\"},\"headline\":\"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks\",\"datePublished\":\"2025-01-25T19:21:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/\"},\"wordCount\":83,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cdn.itpiran.net\\\/2025\\\/01\\\/25224954\\\/Callbacks-3.jpg\",\"keywords\":[\"Java Script\"],\"articleSection\":[\"\u0622\u0645\u0648\u0632\u0634\u06cc\",\"\u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/\",\"url\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/\",\"name\":\"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks - \u0628\u0644\u0627\u06af ITPiran\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cdn.itpiran.net\\\/2025\\\/01\\\/25224954\\\/Callbacks-3.jpg\",\"datePublished\":\"2025-01-25T19:21:24+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#primaryimage\",\"url\":\"https:\\\/\\\/cdn.itpiran.net\\\/2025\\\/01\\\/25224954\\\/Callbacks-3.jpg\",\"contentUrl\":\"https:\\\/\\\/cdn.itpiran.net\\\/2025\\\/01\\\/25224954\\\/Callbacks-3.jpg\",\"width\":1793,\"height\":1110},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/tutorials\\\/understanding-the-event-loop-callbacks\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u0622\u0645\u0648\u0632\u0634\u06cc\",\"item\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/category\\\/tutorials\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/\",\"name\":\"\u0628\u0644\u0627\u06af ITPiran\",\"description\":\"\u0627\u062e\u0628\u0627\u0631 \u0648 \u0645\u0642\u0627\u0644\u0627\u062a \u062a\u062c\u0627\u0631\u062a \u067e\u0627\u06cc\u062f\u0627\u0631 \u0627\u06cc\u0631\u0627\u0646\u06cc\u0627\u0646\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#organization\",\"name\":\"\u0628\u0644\u0627\u06af \u062a\u062c\u0627\u0631\u062a \u067e\u0627\u06cc\u062f\u0627\u0631 \u0627\u06cc\u0631\u0627\u0646\u06cc\u0627\u0646\",\"alternateName\":\"ITPIran Blog\",\"url\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/cdn.itpiran.net\\\/2023\\\/12\\\/27150508\\\/cropped-ITPIRAN-BLOG-LOGO-2.png\",\"contentUrl\":\"https:\\\/\\\/cdn.itpiran.net\\\/2023\\\/12\\\/27150508\\\/cropped-ITPIRAN-BLOG-LOGO-2.png\",\"width\":512,\"height\":512,\"caption\":\"\u0628\u0644\u0627\u06af \u062a\u062c\u0627\u0631\u062a \u067e\u0627\u06cc\u062f\u0627\u0631 \u0627\u06cc\u0631\u0627\u0646\u06cc\u0627\u0646\"},\"image\":{\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/#\\\/schema\\\/person\\\/04ed27b919baca468a2273f8e4318f81\",\"name\":\"admin\",\"url\":\"https:\\\/\\\/www.itpiran.net\\\/blog\\\/es\\\/author\\\/admin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Comprensi\u00f3n del bucle de eventos y las devoluciones de llamadas - Blog de ITPiran","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.itpiran.net\/blog\/es\/tutorials\/understanding-the-event-loop-callbacks\/","og_locale":"es_ES","og_type":"article","og_title":"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks - \u0628\u0644\u0627\u06af ITPiran","og_description":"\u0645\u0642\u062f\u0645\u0647 \u062f\u0631 \u0631\u0648\u0632\u0647\u0627\u06cc \u0627\u0648\u0644\u06cc\u0647 \u0627\u06cc\u0646\u062a\u0631\u0646\u062a\u060c \u0648\u0628 \u0633\u0627\u06cc\u062a \u0647\u0627 \u0627\u063a\u0644\u0628 \u0627\u0632 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u062b\u0627\u0628\u062a \u062f\u0631 \u06cc\u06a9 \u0635\u0641\u062d\u0647 HTML \u062a\u0634\u06a9\u06cc\u0644&hellip;","og_url":"https:\/\/www.itpiran.net\/blog\/es\/tutorials\/understanding-the-event-loop-callbacks\/","og_site_name":"\u0628\u0644\u0627\u06af ITPiran","article_published_time":"2025-01-25T19:21:24+00:00","og_image":[{"width":1793,"height":1110,"url":"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"admin","Tiempo de lectura":"13 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#article","isPartOf":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/"},"author":{"name":"admin","@id":"https:\/\/www.itpiran.net\/blog\/#\/schema\/person\/04ed27b919baca468a2273f8e4318f81"},"headline":"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks","datePublished":"2025-01-25T19:21:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/"},"wordCount":83,"commentCount":0,"publisher":{"@id":"https:\/\/www.itpiran.net\/blog\/#organization"},"image":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg","keywords":["Java Script"],"articleSection":["\u0622\u0645\u0648\u0632\u0634\u06cc","\u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/","url":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/","name":"Comprensi\u00f3n del bucle de eventos y las devoluciones de llamadas - Blog de ITPiran","isPartOf":{"@id":"https:\/\/www.itpiran.net\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#primaryimage"},"image":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg","datePublished":"2025-01-25T19:21:24+00:00","breadcrumb":{"@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#primaryimage","url":"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg","contentUrl":"https:\/\/cdn.itpiran.net\/2025\/01\/25224954\/Callbacks-3.jpg","width":1793,"height":1110},{"@type":"BreadcrumbList","@id":"https:\/\/www.itpiran.net\/blog\/tutorials\/understanding-the-event-loop-callbacks\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.itpiran.net\/blog\/"},{"@type":"ListItem","position":2,"name":"\u0622\u0645\u0648\u0632\u0634\u06cc","item":"https:\/\/www.itpiran.net\/blog\/category\/tutorials\/"},{"@type":"ListItem","position":3,"name":"\u062f\u0631\u06a9 \u062d\u0644\u0642\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f \u0648 callbacks"}]},{"@type":"WebSite","@id":"https:\/\/www.itpiran.net\/blog\/#website","url":"https:\/\/www.itpiran.net\/blog\/","name":"Blog de ITPiran","description":"Noticias y art\u00edculos sobre comercio sostenible en Ir\u00e1n","publisher":{"@id":"https:\/\/www.itpiran.net\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.itpiran.net\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.itpiran.net\/blog\/#organization","name":"Blog sobre negocios iran\u00edes sostenibles","alternateName":"ITPIran Blog","url":"https:\/\/www.itpiran.net\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.itpiran.net\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/cdn.itpiran.net\/2023\/12\/27150508\/cropped-ITPIRAN-BLOG-LOGO-2.png","contentUrl":"https:\/\/cdn.itpiran.net\/2023\/12\/27150508\/cropped-ITPIRAN-BLOG-LOGO-2.png","width":512,"height":512,"caption":"\u0628\u0644\u0627\u06af \u062a\u062c\u0627\u0631\u062a \u067e\u0627\u06cc\u062f\u0627\u0631 \u0627\u06cc\u0631\u0627\u0646\u06cc\u0627\u0646"},"image":{"@id":"https:\/\/www.itpiran.net\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.itpiran.net\/blog\/#\/schema\/person\/04ed27b919baca468a2273f8e4318f81","name":"administraci\u00f3n","url":"https:\/\/www.itpiran.net\/blog\/es\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/posts\/16678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/comments?post=16678"}],"version-history":[{"count":2,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/posts\/16678\/revisions"}],"predecessor-version":[{"id":16685,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/posts\/16678\/revisions\/16685"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/media\/16684"}],"wp:attachment":[{"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/media?parent=16678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/categories?post=16678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.itpiran.net\/blog\/es\/wp-json\/wp\/v2\/tags?post=16678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}