(asynchronous) . .
setTimeout .
. ( ).
src loadScript(src) .
function loadScript(src) {
// <script> .
// src .
let script = document.createElement('script');
script.src = src;
document.head.append(script);
}
loadScript(src) <script src=""> . , .
loadScript(src) .
//
loadScript('/my/script.js');
. .
loadScript() .
loadScript('/my/script.js');
// loadScript
// .
// ...
. , .
loadScript(...) .
loadScript('/my/script.js'); // script.js "function newFunction() {}" .
newFunction(); // !
. loadScript . , . .
loadScript (callback) ( . ).
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
.
loadScript('/my/script.js', function() {
// .
newFunction(); // .
...
});
( ) ( ) .
. .
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
alert(`${script.src} .`);
alert( _ ); //
});
(callback-based) . .
loadScript , .
, ? .
loadScript .
loadScript('/my/script.js', function(script) {
alert(`${script.src} . , .`);
loadScript('/my/script2.js', function(script) {
alert(` .`);
});
});
loadScript , loadScript .
?
loadScript('/my/script.js', function(script) {
loadScript('/my/script2.js', function(script) {
loadScript('/my/script3.js', function(script) {
//
});
})
});
. , . .
. . .
loadScript .
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error(`${src} .`));
document.head.append(script);
}
loadScript callback(null, script), callback(error) .
loadScript .
loadScript('/my/script.js', function(error, script) {
if (error) {
//
} else {
//
}
});
. ' (error-first callback)' .
.
callback.callback(err).- ( ) .
callback(null, result1, result2...).
, .
, . .
.
loadScript('1.js', function(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('2.js', function(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('3.js', function(error, script) {
if (error) {
handleError(error);
} else {
// , . (*)
}
});
}
})
}
});
.
1.js. ,2.js. ,3.js.(*).
. ... .
(callback hell) ' (pyramid of doom)' .
' . .
.
. .
loadScript('1.js', step1);
function step1(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('2.js', step2);
}
}
function step2(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('3.js', step3);
}
}
function step3(error, script) {
if (error) {
handleError(error);
} else {
// . (*)
}
};
? . .
, . . . .
step* ' . . (namespace cluttering).
.
, . '(promise)' .
<code>,<pre>. 10 plnkr, JSBin, codepen .