The JS Event Loop
Unas Preguntas
- ¿Cual es la salida de las llamadas a
console.trace
? (console.trace
muestra la stack trace en la consola)
function multiply(x,y) {
// console.trace imprime una traza de la pila de llamadas
console.trace("-----------At multiply-----------");
return x * y;
}
function squared(n) {
console.trace("-----------At squared-----------");
return multiply(n,n)
}
function printSquare(n) {
return squared(n)
}
let numberSquared = printSquare(5);
console.log(numberSquared);
-
¿En que orden ocurren las salidas?
(function() { console.log('this is the start'); setTimeout(function cb() { console.log('Callback 1: this is a msg from call back'); }); // has a default time value of 0 console.log('this is just a message'); setTimeout(function cb1() { console.log('Callback 2: this is a msg from call back'); }, 0); console.log('this is the end'); })();
- El método
setTimeout(funcion, retraso)
establece un temporizador que ejecutafuncion
después de que transcurre un tiemporetraso
en milisegundos. Si se omite este parámetro se usa el valor 0. El valor retornado identifica el temporizador creado con la llamada asetTimeout()
; este valor puede pasarse aclearTimeout()
para cancelar el temporizador.
- El método
-
¿Cual es la salida?
for(var i=0;i<=3; i++) { setTimeout(()=> console.log(i), 0) }
-
¿Cual es la salida?
const s = new Date().getSeconds(); setTimeout(function() { console.log("Ran after " + (new Date().getSeconds() - s) + " seconds"); }, 500); while(true) { if(new Date().getSeconds() - s >= 2) { console.log("Good, looped for 2 seconds"); break; } }
Unas Figuras
As long as there’s something left to do, JSs event loop will keep spinning. Whenever an event occurs, JS invokes any callbacks (event handlers) that are listening for that event.
- Your JavaScript code runs single threaded. There is just one thing happening at a time.
- Pay attention to how you write your code and avoid anything that could block the thread, like synchronous network calls or long loops.
- In most browsers there is an event loop for every browser tab, to avoid a web page with heavy processing to block your entire browser.
- Web Workers run in their own event loop as well
The Event Loop en el libro The Modern JavaScript Tutorial
- Event Loop
- Use-case 1: splitting CPU-hungry tasks
- Use case 2: progress indication
- Use case 3: doing something after the event
- Macrotasks and Microtasks
- Summary
The section Concurrency model and the event loop at https://developer.mozilla.org/
Repasando las Preguntas a la luz del Bucle de Eventos
Ejemplo: La Pila
Este ejemplo es tomado del vídeo:
se le puede proporcionar a loupe
:
- loupe a tool in the cloud to see the event loop working
Está en este directorio en mi laptop:
~/campus-virtual/1920/sytws1920/ull-mii-sytws-1920.github.io/tema1-introduccion/practicas/p2-t1-c3-file-system/event-loop/callstack.js
Este es el código:
function multiply(x,y) {
// console.trace imprime una traza de la pila
console.trace("-----------At multiply-----------");
return x * y;
}
function squared(n) {
console.trace("-----------At squared-----------");
return multiply(n,n)
}
function printSquare(n) {
return squared(n)
}
let numberSquared = printSquare(5);
console.log(numberSquared);
Orden de Ejecución
Directorio en mi máquina:
tema1-introduccion/practicas/p2-t1-c3-file-system/event-loop/order.js
Sacado de:
- Tutorial Concurrency model and Event Loop at https://developer.mozilla.org
(function() {
console.log('this is the start');
setTimeout(function cb() {
console.log('Callback 1: this is a msg from call back');
}); // has a default time value of 0
console.log('this is just a message');
setTimeout(function cb1() {
console.log('Callback 2: this is a msg from call back');
}, 0);
console.log('this is the end');
})();
Ejemplo: JS is single threaded
En mi máquina:
tema1-introduccion/practicas/p2-t1-c3-file-system/event-loop/settimeout-does-not-run-inmediately.js
Tomado del tutorial:
- Tutorial Concurrency model and Event Loop at https://developer.mozilla.org
const s = new Date().getSeconds();
setTimeout(function() {
console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
}, 500);
while(true) {
if(new Date().getSeconds() - s >= 2) {
console.log("Good, looped for 2 seconds");
break;
}
}
Splitting CPU Hungry Tasks
See https://javascript.info/event-loop#use-case-1-splitting-cpu-hungry-tasks
To demonstrate the approach, for the sake of simplicity, let’s take a function that counts from 1 to a big number.
If you run the code below with a very large number, the engine will hang for some time.
When running it in-browser, try to click other buttons on the page – you’ll see that no other events get handled until the counting finishes.
let i = 0;
let start = Date.now();
function count() {
// do a heavy job
for (let j = 0; j < 1e9; j++) {
i++;
}
alert("Done in " + (Date.now() - start) + 'ms');
}
count();
We can evade problems by splitting the big task into pieces. Do the first piece, then schedule setTimeout (with zero-delay) to do the next piece, and so on.
[~/.../tema2-async/event-loop(master)]$ pwd -P
/Users/casiano/campus-virtual/1920/dsi1920/ull-esit-dsi-1920.github.io/tema2-async/event-loop
[~/.../tema2-async/event-loop(master)]$ cat splitting-cpu-hungry-task.html
<!DOCTYPE html>
<div id="progress"></div>
<script>
'use strict';
let start = Date.now();
let i = 0;
let chunk = () => {
// do a piece of the heavy job (*)
do {
i++;
} while (i % 1e5 != 0);
progress.innerHTML = i;
};
let stop = () => (i == 1e7);
function count(task, condition) {
if (condition()) {
alert("Done in " + (Date.now() - start) + 'ms');
} else {
setTimeout(() => count(task, condition)); // schedule the new call (**)
};
task();
}
count(chunk, stop);
</script>
Web Workers
/local/src/uai/uai2015/simple-web-worker
- Repo de ejemplo simple-web-worker
- Repo de ejemplo fibonacci-worker
- JS Day Canarias. Multithreading in JS Chinenye
- MDN Tutorial: Using Web Workers
Async.js
Race Condition
/local/src/uai/uai2015/race-condition/index.html
- Repo de Ejemplo
- Race Condition in JavaScript YouTube Video
References
- Event loop: microtasks and macrotasks en el libro https://javascript.info
- Tutorial Concurrency model and Event Loop at https://developer.mozilla.org
- The JavaScript Event Loop by Flavio
- Concurrency and Parallel Computing in JavaScript Stephan Herhut. Strange Loop 2013.
- Philip Roberts: ¿Que diablos es el “event loop” (bucle de eventos) de todos modos? (JSConf EU)
- loupe a tool in the cloud to see the event loop working