Reputation: 421
In a HTML file, I have the following scripts:
<head>
<script src="/script1.js" defer></script>
<script src="/script2.js" defer></script>
</head>
In script1
, I am loading another HTML file:
(async function() {
await fetch("./header.html")
.then(response => { return response.text() })
.then(data => { document.getElementById("header").innerHTML = data; });
})()
The code in script2
uses the elements from header.html
which is being loaded by script1
. With the current codes, script2
doesn't wait for header.html
to be completely fetched.
A proof of this is that I have added console.log("1")
after the fetch of script1
, and added console.log("2")
at the beginning of script2
. Even though in the HTML file, I am calling script1
then script2
, but console.log('2')
appears before console.log('1')
Thus causing script2
to read some null elements (which have not been rendered yet). I am trying to ensure that script1
finishes executing (thus the fetch operation finishes) before running script2
. How should I do this?
Upvotes: 7
Views: 2314
Reputation: 23396
await
doesn't block the execution of the entire script. await
s are just hiding promise(s) into a synchronous-looking construction. When await
is met in a function marked as async
, the expression following await
, often a function call, is executed, but the return value is not waited inside the async
function. Instead, the function marked with async
is paused, and the execution continues from the point the async
function was called, and the rest of the script is executed (and perhaps also other scripts), until the promise is fullfilled, Then the script execution resumes to the async
function, and continues from the next statement after the statement where await
operator originally paused the async
function.
You can use a promise like this:
In script1:
const headerHtml = new Promise((resolve, reject) => {
fetch("./header.html")
.then(response => response.text())
.then(data => {
document.getElementById("header").innerHTML = data;
resolve();
});
});
In script2:
headerHtml.then(() => {
// Now header.html is fully loaded
// Do what you need to do with the new elements
});
This will work even when fetch
would had been completely resolved before then
handler is set in script2 (or anywhere in general), because "If the promise has already been fullfilled or rejected when a corresponding handler is attached, the handler will be called"MDN.
Upvotes: 4
Reputation: 97
The easiest way to go is to add the code in script2 to script1, basically having one script tag. For Example :
(async function() {
await fetch("./header.html")
.then(response => { return response.text() })
.then(data => { document.getElementById("header").innerHTML = data})
.then(headerData => {code for script two})
})()
Upvotes: 0
Reputation: 15847
You can combine the two as follows:
(async function() {
await fetch("./header.html")
.then(response => { return response.text() })
.then(data => {
document.getElementById("header").innerHTML = data;
document.getElementById("some element in header.html").style.display = block
});
})()
Upvotes: 0