Sistemas y Tecnologías Web: Servidor

Master de II. ULL. 1er cuatrimestre. 2020/2021


Organization ULL-MII-SYTWS-2021   Classroom ULL-MII-SYTWS-2021   Campus Virtual SYTWS   Chat Chat   Profesor Casiano

Table of Contents

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.

1
2
3
[~/.../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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html>
<style>
  #progress {color:green;}
</style>

<h1>Splitting CPU Hungry Tasks:When you check the checkbox, the  text will change color</h1>
<input type="checkbox" id="checkResponsive">
<button disabled="disabled" id="progress">Click me!</button>

<script>
'use strict';

const checkResponsive = document.getElementById("checkResponsive");
const progress = document.getElementById("progress");
checkResponsive.addEventListener("change", (checkbox) => {
    if (checkResponsive.checked) {
        progress.style.color = "red";
    } else{
        progress.style.color = "green";
   }
  }
);

let start = Date.now();

const Big   = 1e9;
const Small = 1e5;

let counter = 0;

let processChunk = (chunk) => {
  let i = chunk;
  do { // do a piece of the heavy job (*)
    i++;
  } while (i % Small != 0);
  progress.innerHTML = i;
  return i;
};

let stop = () => (counter == Big);

function count() { 
  if (stop()) {
    progress.innerHTML = "Done in " + (Date.now() - start) + 'ms';
  } else {
    setTimeout(count); // schedule the new call (**)
  };
  counter = processChunk(counter);
}

count();
</script>

RUN IT!!!!

Comment with GitHub Utterances

Comment with Disqus

thread de discusion