# Race Condition: Loading an image with some delay

# The code

Consider this file index.html:

<!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Asynchronous Image Loading</title>
</head>
<body>
  <div id="holder-div"></div>

  <script type="text/javascript">
    let image = new Image(100),
        //url = "https://elementscpa.com/wp-content/uploads/2017/08/elementscpa-business-infinity-loop-tal-e1504182065499.png", 
        url = "infinity-loop.png", 
        container = document.getElementById("holder-div");

    image.src = url; // I suppose the "load" process starts here

    let waitFor = 0;
    //let waitFor = 2000;
    setTimeout(function(){
      // The onload event occurs when an object has been loaded
      // We only append it to the container when the load has finished
      // The handler is inserted in the event queueAfter after 'waitFor' ms 
      // If an EventListener is added to an EventTarget while it is 
      // processing an event, that event does not trigger the listener.
      image.addEventListener("load", function() {
        console.trace();
        container.appendChild(image)
      });
    }, waitFor);

  </script>
  <a href="http://www.infoq.com/presentations/javascript-concurrency-parallelism">Concurrency and Parallel Computing in JavaScript (Recorded at: StrangeLoop) by Stephan Herhut on Mar 05, 2014 </a>
</body>
</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

Typically a browser will not wait for one image to be downloaded before requesting the next resource or image (opens new window). It will request all images simultaneously, as soon as it gets the srcs of those images.

The EventTarget.addEventListener() method of the EventTarget (opens new window) sets up a function that will be called whenever the specified event is delivered to the target.

# The Experiment

Install http-server (opens new window).

Then serve this index.html file with:

http-server -p 9000 -o
1

with this line uncommented

let waitFor = 2000;
1

Can you see the infinite loop image?

Now comment the line where waitFor is initialized and uncomment the other:

let waitFor = 0;
1

and run:

http-server -p 8000 -o
1

(Change the port to avoid cache problems)

What do you think it will happen? Can you explain it?

# Think

Here is again our image of the event loop:

# Comments

El código:

 image.addEventListener("load", function() {
        console.trace();
        container.appendChild(image)
      });
1
2
3
4

hace que el evento load sea registrado en el elemento image que ha sido creado dinámicamente, pero el setTimeout que lo envuelve hace que dicho registro ocurra después de al menos waitFor milisegundos.

Por tanto, si pasa cierto tiempo es posible que el evento load (la carga de la imagen) haya ocurrido antes que el manejador sea registrado.

Event listeners are not called if they are attached after the event has already fired. "You snooze, you lose."

# Test adicional

Con let waitFor = 0 pruebe a recargar la página. ¿Que ocurrirà? ¿Pasa lo mismo con todos los navegadores?


# Objetivo

In your report, develop an explanation for the observed behaviors.

# Referencias

Grading Rubric#

Comments#

Last Updated: 3 months ago