如何使用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
。添加一个版本号,该版本号在每次更改脚本时都会出现冲突,以便用户下载最新版本,而不是从本地系统加载旧版本。