Reputation: 65
I new to JS and was learning callbacks and how asynchrony happens with the callbacks. I came across code on https://javascript.info/callbacks which is
function loadScript(src) {
let script = document.createElement('script');
script.src = src;
document.head.append(script);
}
loadScript('/my/script.js');
// the code below loadScript doesn't wait for the script loading to finish
// ...
So, it is said that loadScript function is executed asynchronously but WHY? as far as I know asynchony happens with functions like setTimeOut or xhr object which are executed via event loop. So, why if we only create element in loadScript function, it is executed asynchronously
Upvotes: 0
Views: 65
Reputation: 53198
The wording in the article is poorly written.
The function is called “asynchronously,” because the action (script loading) finishes not now, but later.
The function call is synchronous. The loading of /my/script.js
is asynchronous, because JS does not wait for the file to be loaded before continuing with its call stack. Any script
elements created using createElement
are loaded asyncrhonously - you can read more about it here:
Dynamically inserted scripts (using
document.createElement()
) load asynchronously by default
The following is a better example of asynchronous calling:
let script = document.createElement('script');
script.src = '/my/script.js';
document.head.append(script);
script.onload = function()
{
// Any code defined inside here is now truly asynchronous.
// It will not be called until /my/script.js has been loaded.
}
Upvotes: 4
Reputation: 113866
Because of how the <script>
tag works. Browsers will load the <script>
tag synchronously except when:
it has an async
tag set to true
it has been created using document.createElement()
So the loadScript
function does the second part.
see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
Upvotes: 1
Reputation: 10384
Why should it wait? You are adding an element to DOM, which performs a HTTP request. If we should wait every request performed by DOM elements then out page would be incredibly slow (Yes, I'm simplifying).
By the way, you have to wait that the onload
event is fired on the element, then you can be sure that the script has been loaded:
function loadScript(src, cb) {
let script = document.createElement('script');
script.src = src;
script.onload = cb;
script.onerror = cb;
document.head.append(script);
}
loadScript('/my/script.js', function (response) {
// Your asynchronous code here
});
In this example I used callback, since it's the easier to understand. But you can easily convert it to Promise
s or async / await
:
function loadScript(src) {
let script = document.createElement('script');
script.src = src;
document.head.append(script);
return new Promise((res, rej) => { // ES6 only
script.onload = res;
script.onerror = rej;
});
}
loadScript('/my/script.js')
.then(() => {
// Your asynchronous code here
})
.catch(() => {
// Error handling
});
Or:
(async function () {
await loadScript('/my/script.js');
// Your async code here
})();
Where the definition of loadScript
is like above
Upvotes: 1