如何使用Javascript按顺序动态加载内部脚本
我有几个脚本需要按特定顺序动态包含。我在这里查看并尝试了几个答案: 我的问题是,这里的答案要么因为异步加载文件而在我的应用程序中不起作用,要么因为加载外部脚本而使问题变得过于复杂。我需要动态加载的脚本是内部的。(即:在我的站点服务器上) 除了许多其他尝试之外,我还尝试了:如何使用Javascript按顺序动态加载内部脚本,javascript,jquery,Javascript,Jquery,我有几个脚本需要按特定顺序动态包含。我在这里查看并尝试了几个答案: 我的问题是,这里的答案要么因为异步加载文件而在我的应用程序中不起作用,要么因为加载外部脚本而使问题变得过于复杂。我需要动态加载的脚本是内部的。(即:在我的站点服务器上) 除了许多其他尝试之外,我还尝试了: $.when( $.getScript('/1.js'), $.getScript('/2.js'), $.getScript('/3.js'),
$.when(
$.getScript('/1.js'),
$.getScript('/2.js'),
$.getScript('/3.js'),
$.getScript('/4.js'),
$.getScript('/5.js'),
$.Deferred(function (deferred) {
$(deferred.resolve);
})
).done(function() {
//Do Something
});
但这并没有按照正确的顺序加载脚本,并导致了一系列错误
此外,我需要加载的脚本是内部的,我不认为需要所有的AJAX
我还尝试了其他变体,但都没有用,希望有人能说明我如何能够一个接一个地动态加载内部脚本,最好不用AJAX调用,而且过于复杂?
getScript
返回类似承诺的对象,因此,您可以在循环中等待它的每次调用,以便串行处理它们:
(async () => {
for (const path of ['/1.js', '/2.js', '/3.js']) {
await $.getScript(path);
}
// Do something
})()
.catch((err) => {
// Something went wrong
});
在纯js中
['/1.js', '/2.js', '/3.js', '/4.js', '/5.js'].forEach(function(script) {
var scriptElement = document.createElement("script");
scriptElement.src = script;
// append script element where you want (head or body)
document.head.appendChild(scriptElement);
});
对于任何使用jQuery的人,我已经改进了@adeneo脚本,这样它将按照指定的顺序加载所有脚本。它不进行链式加载,因此速度非常快,但如果您想要更快,请更改50毫秒的等待时间
$.getMultiScripts = function(arr, path) {
function executeInOrder(scr, code, resolve) {
// if its the first script that should be executed
if (scr == arr[0]) {
arr.shift();
eval(code);
resolve();
console.log('executed', scr);
} else {
// waiting
setTimeout(function(){
executeInOrder(scr, code, resolve);
}, 50);
}
}
var _arr = $.map(arr, function(scr) {
return new Promise((resolve) => {
jQuery.ajax({
type: "GET",
url: (path || '') + scr,
dataType: "text",
success: function(code) {
console.log('loaded ', scr);
executeInOrder(scr, code, resolve);
},
cache: true
});
});
});
_arr.push($.Deferred(function( deferred ){
$( deferred.resolve );
}));
return $.when.apply($, _arr);
}
如何使用:
var script_arr = [
'myscript1.js',
'myscript2.js',
'myscript3.js'
];
$.getMultiScripts(script_arr, '/mypath/').done(function() {
// all scripts loaded
});
除非您可以在HTML中包含脚本(事实似乎并非如此),否则您必须使用Ajax或某些网络请求来获取脚本,对吗?@CertainPerformance我对AJAX的需求不太清楚,但如果有必要的话,即使是内部脚本也能为我解释这一点,但我仍然不知道如何同步加载这些脚本,我欢迎并感谢任何指导。不管怎样,我还在别的地方读书。谢谢如果必须按顺序执行,那么您需要将$.getScript
调用链接到前一个调用的回调中。您是否正在为站点使用SPA体系结构?我在试图确定异步加载脚本的原因时询问;这通常比它的价值要麻烦得多。@RoryMcCrossan对不起,IDK什么是温泉建筑。可能不会。只有少数脚本依赖于前面的每个脚本。通过将它们包含在HTML中,它工作得非常出色。只有当用户点击按钮时,网站才需要它们。所以,如果这是为了优化而做的,那么它就不是正确的方法。我建议使用绑定和缩小JS(和CSS)来代替。这样,所有脚本都会加载一次并缓存。任何后续页面请求在缓存时都不会有JS/CSS的加载时间。它还避免了您必须发出的AJAX请求的复杂性,以及您将遇到的加载障碍。我能不能让你有兴趣用类似于$的方式来包装这个(…我发布的脚本?我不知道如何理解:“(async()=>{”并且能够采取步骤await
只能在async
函数中使用,因此async和iLife.async函数返回承诺,如果函数中的任何等待项被拒绝,承诺将被拒绝,因此外部需要.catch
来处理错误。也可以在函数内部使用try/catch在等待中生活,但在等待中生活。.catch(
兑现承诺在我看来要美好得多。你不需要用$来包装它。当(
或其他任何事情发生时,这会使事情变得不必要的复杂;上面答案中的代码应该很有用,谢谢。如果你是“性能”,我现在就卷起袖子名字和赛车运动有关,你会喜欢我的网站的。顺便说一句,因为我们使用的是AJAX,而且我读到getScript不缓存,我们可以在这里添加一个简单的行程序,让用户在机器上缓存这些脚本一天吗?添加缓存机制会复杂得多。你可以存储每个脚本都会产生localStorage
或类似的结果,然后在调用getScript
之前检查localStorage
。添加一个版本号,该版本号在每次更改脚本时都会出现冲突,以便用户下载最新版本,而不是从本地系统加载旧版本。