7

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?

6
  • 1
    One simple way is to add the functionality from script2 into last the then of script1. Or at least call the script2 function in the promise of script1. Commented Sep 28, 2020 at 19:39
  • could you show the script2 code Commented Sep 28, 2020 at 19:40
  • How about npmjs.com/package/loadjs ? I think this does what you need, but it requires an additional library... Commented Sep 28, 2020 at 19:41
  • script2 simply does document.getElementById("some element in header.html").style.display = block, but it generates an error of element undefined. Commented Sep 28, 2020 at 19:45
  • 1
    Multiple scripts with the defer attribute are added to a list of scripts to be executed once the document they are part of has completed loading. Whether they are executed in order is up to the parser. See this answer to a similar question; basically, once you use defer, you've given up control on execution order. Commented Sep 28, 2020 at 19:59

3 Answers 3

4

await doesn't block the execution of the entire script. awaits 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.

Sign up to request clarification or add additional context in comments.

Comments

0

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
});
})()

Comments

0

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})
})()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.