'$.getScript not returning script contents and promise can't be resolved [duplicate]
I return within an ajax request a custom html tag:
<eval-script src="script1.js"></eval-script>
<eval-script src="script2.js"></eval-script>
<eval-script src="script3.js"></eval-script>
Then I parse the response and store all script executions in an array (arrow functions):
const evalArray = [];
const getScript = function(src, dfd) {
$.getScript(src)
.done(function() {
dfd.resolve();
})
.fail(function() {
dfd.reject();
});
}
const evalScripts = document.querySelectorAll("eval-script");
for (const script of evalScripts) {
const src = script.getAttribute("src");
evalArray.push((dfd) => getScript(src, dfd));
};
After that I iterate through the array and try to wait for script to be loaded (non-deferred, synchronous):
evalArray.forEach((func) => {
const dfd = $.Deferred();
func(dfd);
while (dfd.state() === "pending") {
console.log("wait for resolve (" + dfd.state() + "): " + func);
};
return;
});
This is done because I want the scripts to execute in the submitted order and they could rely on the previous script. Also I want to execute some script after that that relies on the scripts being loaded.
Unfortunatly I can see $.getScript is requesting the script, and the scripts response headers are shown in browsers network tab, but there is no content and the promises done or fail are not executed.
The scripts can be opened by url in browser with no problem. Also I can execute "$.getScript('script1.js')" in console without any problem.
I do not want to use synchronous Ajax because that is deprecated option in jquery. Also I have no problem with promise setup, but getScript is not executing as expected.
Can someone please help?
Solution 1:[1]
Final solution:
My ajax request is now calling a async function on success (done promise):
$.ajax({
...
}).done(function(data, textStatus, jqXHR) {
onSuccess();
})
Within onSuccess function I placed async code from above, but I am awaiting the promise in addition:
async function onSuccess() {
async function loadScripts() {
const evalScripts = document.querySelectorAll("eval-script[src]");
for (const script of evalScripts) {
const src = script.getAttribute("src");
await $.getScript(src);
}
}
await loadScripts();
}
This way I can access and execute each object/function from the evaluated scripts directly after calling "await loadScripts()".
My thanks goto @jfriend00 pushing me the right way and clarifying async await execution in javascript.
Solution 2:[2]
My code now looks like this according to @jfriend00 suggestion:
async function loadScripts() {
const evalScripts = document.querySelectorAll("eval-script");
for (const script of evalScripts) {
const src = script.getAttribute("src");
await $.getScript(src);
console.log("getScript done: " + src);
}
}
loadScripts().then(result => {
console.log("all done loading scripts: " + result);
}).catch(err => {
console.log(err);
});
console.log("eval done!");
Unfortunately the script is not waiting for all scripts to be loaded as console output is:
eval done!
getScript done: script.js
getScript done: script2.js
getScript done: script3.js
getScript done: script4.js
getScript done: script5.js
all done loading scripts: undefined
How do I make the script wait for all scripts to be loaded?
And as I see, async await is ECMA2016 feature. How widely is is supported by browsers?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Darth Sonic |
| Solution 2 |
