-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Pointed out by @jonco3.
The script fetching algorithms all use an "asynchronous completion" framework, which is not very well-defined. See whatwg/infra#181.
In particular, several people assume that "async" means "queue a task". But it's quite possible to not end up queuing a task, e.g. if you "fetch the descendants of and instantiate" a module with no descendants. So then the presence of the words "when this asynchronously completes" causes confusion.
The particular case we were concerned with was "prepare a script" step 25 for src-less module scripts, which says
Fetch the descendants of and instantiate script, given the destination "script". When this asynchronously completes, set the script's script to the result. At that time, the script is ready.
In code, the case in question is a classic inline script that inserts a module inline script:
<script>
console.log(1);
const s = document.createElement("script");
s.type = "module";
s.textContent = "console.log(2);";
document.body.appendChild(s);
console.log(3);
</script>
There are a couple of possible dimensions of consistency here:
- Have no-dependency module scripts be consistent with classic scripts, and have them execute immediately (logs 1 2 3).
- Have no-dependency module scripts be consistent with dependency-having module scripts, and have them execute from a queued task (logs 1 3 2).
Currently the spec picks (1), but in a confusing way because of the use of the word "asynchronously" which causes people to think maybe it's (2).
/cc @whatwg/modules. I'd love folks thoughts on whether (1) or (2) is more natural.
Side note: if we pick (2), then we should remove the "set currentScript to null" logic inside "execute a script block", since currentScript will always be null anyway.
Also, I might have gotten something wrong here, as this is subtle stuff; please feel free to check my logic.