Procesadores de Lenguajes

3º. 2º cuatrimestre. Itinerario de Computación. Grado en Ingeniería Informática. ULL


Organization ULL-ESIT-PL-1920   Github Classroom ULL-ESIT-PL-1920   Campus Virtual PL   Chat Chat   Profesor Casiano

Table of Contents

The JS Event Loop

Unas Preguntas

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);

Unas Figuras

<i>All JavaScript environments use an event loop</i>
All JavaScript environments use an event loop

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.

<i>There’s an endless loop, when JavaScript engine waits for tasks, executes them and then sleeps waiting for more tasks</i>
There’s an endless loop, when JavaScript engine waits for tasks, executes them and then sleeps waiting for more tasks

The Event Loop en el libro The Modern JavaScript Tutorial

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:

Está en este directorio en mi laptop:

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);

Output from execution

Orden de Ejecución

Directorio en mi máquina:

tema1-introduccion/practicas/p2-t1-c3-file-system/event-loop/order.js 

Sacado de:

(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:

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

Async.js

Race Condition

/local/src/uai/uai2015/race-condition/index.html

References

Your Comments

Comment with Disqus