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

Descripción de la Práctica p8-t2-async-serialize

Se dispone de una función loadScript que permite la carga de un script:

1
2
3
4
5
6
7
8
9
    function loadScript(src, callback) {
        let script = document.createElement('script');
        script.src = src;
      
        script.onload = () => callback(null, script);
        script.onerror = () => callback(new Error(`Script load error for ${src}`));
      
        document.head.append(script);
      }

Que puede ser usada para cargar varios scripts. Supongamos que el segundo script usa funciones definidas en el primero. Tenemos que asegurarnos que el segundo script sólo se carga una vez terminada la carga del primero. En este ejemplo de uso cargamos tres scripts script-1.js, script-2.js y script-3.js:

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
54
55
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    <p id="out"></p>
    <script>
      'use strict';
      let out = document.querySelector('p');

      function loadScript(src, callback) {
        let script = document.createElement('script');
        script.src = src;
      
        script.onload = () => callback(null, script);
        script.onerror = () => callback(new Error(`Script load error for ${src}`));
      
        document.head.append(script);
      }
           
      loadScript('script-1.js', (error, script) => {
        if (error) {
          console.error( error ); 
        } else {
          const message = `Cool!, the script '${script.src}' is loaded: "${hello()}"`;
          out.innerHTML = message;
          console.log(message);

          loadScript('script-2.js', (error, script) => {
            if (error) {
              console.error( error ); 
            } else {
              const message = `Great!, the script '${script.src}' is loaded: "${world()}"`;
              out.innerHTML += `<br/>${message}`;
              console.log(message);
              loadScript('script-3.js', (error, script) => {
                if (error) {
                  console.error( error );
                } else {
                  const message = `Unbelievable!, the script '${script.src}' is loaded: "${ull()}"`;
                  out.innerHTML += `<br/>${message}`;
                  console.log(message);
                  // ...continue after all scripts are loaded 
                }
              });
            }
          })
        }
      });
      </script>      
  </body>  
</html>

Puede ver este código en funcionamiento visitando https://ull-esit-pl.github.io/async-js-series-webpack/load-script.html. Si lo hace, recuerde abrir las herramientas de desarrollador para ver los mensajes en la cónsola. Puede encontrar mas detalles sobre este ejercicio en el tutorial del profesor en https://github.com/ULL-ESIT-PL/async-js-series-webpack.

  1. Escriba una función loadScripts

    1
    2
    3
    4
    
     loadScripts(
       ['script-1.js', 'script-2.js', 'script-3.js'], 
       (err, results) => out.innerHTML = results.map(s => s.src).join("<br/>")
     )
    

    que carga los scripts especificados en el array en secuencia y llama a la callback pasada como último argumento bien con un error si lo hubo o con el array de resultados (los scripts).

  2. Escriba su propia versión de la función series (con la misma interfaz que su equivalente de Async.js) que resuelva el problema de la secuencialización de las callbacks:

    1
    2
    3
    4
    5
    6
    7
    8
    
     series(
         [
             cb => loadScript('script-1.js', cb),
             cb => loadScript('script-2.js', cb),
             cb => loadScript('script-3.js', cb)
         ],
         (err, results) => p.innerHTML = results.map(s => s.src).join("<br/>")
     );
    
  3. Deje su solución al reto #number en un fichero reto-#number.html

Observaciones

Si hace las pruebas de funcionamiento con scripts de similar tamaño la probabilidad de que su algoritmo produzca una salida que respeta el orden especificado es alta, incluso si su algoritmo es erróneo.

Puede simular que los scripts son de distinto tamaño retrasando la iniciación de las cargas con un setTimeout que espere por un número aleatorio de milisegundos:

1
2
3
  [~/.../load-script-seq(private)]$ pwd
/Users/casiano/local/src/javascript/learning/async/load-script-seq
[~/.../load-script-seq(private)]$ sed -ne '12,23p' load-scripts.html
1
2
3
4
5
6
7
8
9
10
11
12
      const ir = (min, max) =>  Math.round((Math.random() * (max - min) + min))
      let out = document.querySelector('p');

      function loadScript(src, callback) {
        let script = document.createElement('script');
        setTimeout(() => script.src = src, ir(500,2000));

        script.onload = () => callback(null, script);
        script.onerror = () => callback(new Error(`Script load error for ${src}`));

        document.head.append(script);
      }

Referencias

Soluciones

  • Solución
  • 1
    2
    
        [~/.../load-script-seq(private)]$ pwd -P
        /Users/casiano/local/src/javascript/learning/async/load-script-seq
    
  • /Volumes/2020/sytws/sytws2021/p8-t2-async-serialize-12-03-2020-09-16-48/alu0101040882 Daniel Labena

Comment with GitHub Utterances

Comment with Disqus

thread de discusion