Master de II. ULL. 1er cuatrimestre. 2020/2021
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.
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).
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/>")
);
Deje su solución al reto #number
en un fichero reto-#number.html
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);
}
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