-
Notifications
You must be signed in to change notification settings - Fork 229
Microtasks #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Microtasks #280
Changes from 3 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
8c2769f
microtasks
vplentinax 9b0e21b
Update article.md
vplentinax cc8313c
Update article.md
vplentinax ffaf1fd
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 864bd4d
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax b636da4
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 76075aa
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 58241d2
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 8c5a040
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 8a82814
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 24cbe56
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax 82b3221
Update 1-js/11-async/07-microtask-queue/article.md
vplentinax File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,112 +1,112 @@ | ||
|
|
||
| # Microtasks | ||
| # Microtareas (Microtasks) | ||
|
|
||
| Promise handlers `.then`/`.catch`/`.finally` are always asynchronous. | ||
| Los manejadores o controladores (en adelante controladores) de Promesas `.then`/`.catch`/`.finally` son siempre asincrónicos. | ||
|
|
||
| Even when a Promise is immediately resolved, the code on the lines *below* `.then`/`.catch`/`.finally` will still execute before these handlers. | ||
| Incluso cuando una Promesa es inmediatamente resuelta, el código en las líneas *debajo de* `.then`/`.catch`/`.finally` se ejecutará antes que estos controladores. | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| Here's a demo: | ||
| Veamos una demostración: | ||
|
|
||
| ```js run | ||
| let promise = Promise.resolve(); | ||
|
|
||
| promise.then(() => alert("promise done!")); | ||
| promise.then(() => alert("¡Promesa realizada!")); | ||
|
|
||
| alert("code finished"); // this alert shows first | ||
| alert("código finalizado"); // esta alerta se muestra primero | ||
| ``` | ||
|
|
||
| If you run it, you see `code finished` first, and then `promise done!`. | ||
| Si ejecutas esto, verás `código finalizado` primero, y después `¡promesa realizada!`. | ||
|
|
||
| That's strange, because the promise is definitely done from the beginning. | ||
| Es algo extraño, porque la promesa se realiza por completo desde el principio. | ||
|
|
||
| Why did the `.then` trigger afterwards? What's going on? | ||
| ¿Por qué `.then` se disparó después? ¿Qué está pasando? | ||
|
|
||
| ## Microtasks queue | ||
| ## Cola de microtareas (Microtasks queue) | ||
|
|
||
| Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue `PromiseJobs`, more often referred to as the "microtask queue" (ES8 term). | ||
| Las tareas asincrónicas necesitan una gestion adecuada. Para ello, el estándar ECMA especifica una cola interna `PromiseJobs`, en ocasiones más conocida como "cola de microtareas" (término ES8). | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| As stated in the [specification](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues): | ||
| Como se indica en la [especificación](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues): | ||
|
|
||
| - The queue is first-in-first-out: tasks enqueued first are run first. | ||
| - Execution of a task is initiated only when nothing else is running. | ||
| - La cola es first-in-first-out (FIFO), es decir, primero en entrar primero en salir: la tarea que entró primero en la cola, será la primera en ejecutarse. | ||
| - La ejecución de una tarea se inicia sólo cuando *no* se está ejecutando nada más. | ||
|
|
||
| Or, to say more simply, when a promise is ready, its `.then/catch/finally` handlers are put into the queue; they are not executed yet. When the JavaScript engine becomes free from the current code, it takes a task from the queue and executes it. | ||
| O, en palabras más simples, cuando una promesa está lista, sus controladores `.then/catch/finally` se ponen en la cola; ellos aún no se ejecutan. Cuando el motor de Javascript se libera del código actual, toma una tarea de la cola y la ejecuta. | ||
|
|
||
| That's why "code finished" in the example above shows first. | ||
| Es por eso que el "código finalizado" en el ejemplo anterior se muestra primero. | ||
|
|
||
|  | ||
|
|
||
| Promise handlers always go through this internal queue. | ||
| Los controladoes de promesas siempre pasan por esta cola interna. | ||
|
|
||
| If there's a chain with multiple `.then/catch/finally`, then every one of them is executed asynchronously. That is, it first gets queued, then executed when the current code is complete and previously queued handlers are finished. | ||
| Si hay una cadena con múltiples `.then/catch/finally`, entonces cada uno de ellos se ejecuta de forma asincrónica. Es decir, primero se pone en la cola, luego se ejecuta cuando se completa el código actual y se finalizan los controladores previamente en la cola. | ||
|
|
||
| **What if the order matters for us? How can we make `code finished` run after `promise done`?** | ||
| **¿Qué pasa si lo que estamos pidiendo es importante? ¿Cómo podemos hacer que `código finalizado` se ejecute después de `¡promesa realizada!`?** | ||
|
|
||
| Easy, just put it into the queue with `.then`: | ||
| Fácil, solo ponlo en la cola con `.then`: | ||
|
|
||
| ```js run | ||
| Promise.resolve() | ||
| .then(() => alert("promise done!")) | ||
| .then(() => alert("code finished")); | ||
| .then(() => alert("promesa realiazada!")) | ||
| .then(() => alert("código finalizado")); | ||
| ``` | ||
|
|
||
| Now the order is as intended. | ||
| Ahora lo pedido es lo previsto. | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Unhandled rejection | ||
| ## Rechazo no controlado | ||
|
|
||
| Remember the `unhandledrejection` event from the article <info:promise-error-handling>? | ||
| Recuerdas el evento `unhandledrejection` de el artículo <info:promise-error-handling>? | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| Now we can see exactly how JavaScript finds out that there was an unhandled rejection. | ||
| Ahora podemos ver exactamente cómo Javascript descubre que hubo un rechazo no controlado o *unhandled rejection* | ||
|
|
||
| **An "unhandled rejection" occurs when a promise error is not handled at the end of the microtask queue.** | ||
| **Se produce un "rechazo no controlado" cuando no se maneja un error de promesa al final de la cola de microtareas.** | ||
|
|
||
| Normally, if we expect an error, we add `.catch` to the promise chain to handle it: | ||
| Normalmente, si esperamos un error, agregamos `.catch` a la cadena de promesa para controlarlo: | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```js run | ||
| let promise = Promise.reject(new Error("Promise Failed!")); | ||
| let promise = Promise.reject(new Error("¡Promesa fallida!")); | ||
| *!* | ||
| promise.catch(err => alert('caught')); | ||
| promise.catch(err => alert('atrapado')); | ||
| */!* | ||
|
|
||
| // doesn't run: error handled | ||
| // no se ejecuta: error controlado | ||
| window.addEventListener('unhandledrejection', event => alert(event.reason)); | ||
| ``` | ||
|
|
||
| But if we forget to add `.catch`, then, after the microtask queue is empty, the engine triggers the event: | ||
| Pero si olvidas añadir el `.catch`, entonces, después de que la cola de microtareas esté vacía, el motor activa el evento: | ||
|
|
||
| ```js run | ||
| let promise = Promise.reject(new Error("Promise Failed!")); | ||
| let promise = Promise.reject(new Error("¡Promesa fallida!")); | ||
|
|
||
| // Promise Failed! | ||
| // Promesa fallida! | ||
| window.addEventListener('unhandledrejection', event => alert(event.reason)); | ||
| ``` | ||
|
|
||
| What if we handle the error later? Like this: | ||
| ¿Qué pasa si controlamos el error más tarde? Como esto: | ||
|
|
||
| ```js run | ||
| let promise = Promise.reject(new Error("Promise Failed!")); | ||
| let promise = Promise.reject(new Error("¡Promesa fallida!")); | ||
| *!* | ||
| setTimeout(() => promise.catch(err => alert('caught')), 1000); | ||
| setTimeout(() => promise.catch(err => alert('atrapado')), 1000); | ||
| */!* | ||
|
|
||
| // Error: Promise Failed! | ||
| // Error: ¡Promesa fallida! | ||
| window.addEventListener('unhandledrejection', event => alert(event.reason)); | ||
| ``` | ||
|
|
||
| Now, if we run it, we'll see `Promise Failed!` first and then `caught`. | ||
| Ahora si nosotros ejecutamos, veremos `¡Promesa fallida!` primero y después `atrapado`. | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| If we didn't know about the microtasks queue, we could wonder: "Why did `unhandledrejection` handler run? We did catch and handle the error!" | ||
| Si no supiéramos acerca de la cola de microtareas podríamos preguntarnos: "¿Porqué se ejecutó el controlador `unhandledrejection`? ¡Capturamos y manejamos el error! | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| But now we understand that `unhandledrejection` is generated when the microtask queue is complete: the engine examines promises and, if any of them is in the "rejected" state, then the event triggers. | ||
| Pero ahora entendemos que `unhandledrejection` se genera cuando se completa la cola de microtareas: el motor examina las promesas y, si alguna de ellas está en el estado "rechazado", entonces el evento se dispara. | ||
|
|
||
| In the example above, `.catch` added by `setTimeout` also triggers. But it does so later, after `unhandledrejection` has already occurred, so it doesn't change anything. | ||
| En el ejemplo anterior, `.catch` agregado por `setTimeout` también se dispara. Pero lo hace más tarde, después de que `unhandledrejection` ya ha ocurrido, por lo que no cambia nada. | ||
|
|
||
| ## Summary | ||
| ## Resumen | ||
|
|
||
| Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (ES8 term). | ||
| El control de promesas siempre es asíncrono, ya que todas las acciones de promesa pasa por la cola interna de "PromiseJobs", también llamada "cola de microtareas" (término ES8). | ||
|
vplentinax marked this conversation as resolved.
Outdated
|
||
|
|
||
| So `.then/catch/finally` handlers are always called after the current code is finished. | ||
| Entonces, los controladores `.then/catch/finally` siempre se llaman después de que el código actual ha finalizado. | ||
|
|
||
| If we need to guarantee that a piece of code is executed after `.then/catch/finally`, we can add it into a chained `.then` call. | ||
| Si necesitamos garantizar que un código se ejecute después de `.then/catch/finally`, podemos agregarlo a una llamada encadenada `.then`. | ||
|
|
||
| In most Javascript engines, including browsers and Node.js, the concept of microtasks is closely tied with the "event loop" and "macrotasks". As these have no direct relation to promises, they are covered in another part of the tutorial, in the article <info:event-loop>. | ||
| En la mayoría de los motores de Javascript, incluidos los navegadores y Node.js, el concepto de microtareas está estrechamente relacionado con el "bucle de eventos" o "event loop" y "macrotareas" o "macrotasks". Como estos no tienen relación directa con las promesas, están cubiertos en otra parte del tutorial, en el artículo <info:event-loop>. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.