Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用jQuery$.getScript()方法包含多个js文件_Javascript_Jquery_Html_Promise - Fatal编程技术网

Javascript 如何使用jQuery$.getScript()方法包含多个js文件

Javascript 如何使用jQuery$.getScript()方法包含多个js文件,javascript,jquery,html,promise,Javascript,Jquery,Html,Promise,我正在尝试将javascript文件动态地包含到我的js文件中。我对此做了一些研究,发现jQuery$.getScript()方法是一种理想的方法 // jQuery $.getScript('/path/to/imported/script.js', function() { // script is now loaded and executed. // put your dependent JS here. // what if the JS code is dep

我正在尝试将javascript文件动态地包含到我的js文件中。我对此做了一些研究,发现jQuery$.getScript()方法是一种理想的方法

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
    // script is now loaded and executed.
    // put your dependent JS here.
    // what if the JS code is dependent on multiple JS files? 
});
但是我想知道这个方法是否可以一次加载多个脚本?我之所以问这个问题,是因为有时候我的javascript文件依赖于多个js文件

先谢谢你

使用或(包括yepnope.js作为
modernizer.load

更新

function getScripts( scripts, onScript, onComplete )
{
    this.async = true;
    this.cache = false;
    this.data = null;
    this.complete = function () { $.scriptHandler.loaded(); };
    this.scripts = scripts;
    this.onScript = onScript;
    this.onComplete = onComplete;
    this.total = scripts.length;
    this.progress = 0;
};

getScripts.prototype.fetch = function() {
    $.scriptHandler = this;
    var src = this.scripts[ this.progress ];
    console.log('%cFetching %s','color:#ffbc2e;', src);

    $.ajax({
        crossDomain:true,
        async:this.async,
        cache:this.cache,
        type:'GET',
        url: src,
        data:this.data,
        statusCode: {
            200: this.complete
        },
        dataType:'script'
    });
};

getScripts.prototype.loaded = function () {
    this.progress++;
    if( this.progress >= this.total ) {
        if(this.onComplete) this.onComplete();
    } else {
        this.fetch();
    };
    if(this.onScript) this.onScript();
};
接下来,这里有一个与您目前使用的yepnope相当的示例,显示了对多个脚本的依赖关系:

yepnope({
  load: ['script1.js', 'script2.js', 'script3.js'],
  complete: function () {
      // all the scripts have loaded, do whatever you want here
  }
});

你要找的是一个AMD兼容的加载器(比如require.js)

如果你查一下,有很多好的开源软件。基本上,这允许您定义一个代码模块,如果它依赖于其他代码模块,它将等待这些模块完成下载后再继续运行。通过这种方式,您可以异步加载10个模块,即使其中一个模块依赖于其他几个模块运行,也应该没有问题。

答案是 您可以将承诺与
getScript()
一起使用,并等待所有脚本加载完毕,例如:

$.when(
    $.getScript( "/mypath/myscript1.js" ),
    $.getScript( "/mypath/myscript2.js" ),
    $.getScript( "/mypath/myscript3.js" ),
    $.Deferred(function( deferred ){
        $( deferred.resolve );
    })
).done(function(){
    
    //place your code here, the scripts are all loaded
    
});

在上面的代码中,在
$()
中添加一个延迟函数并解析它就像在jQuery调用中放置任何其他函数一样,就像
$(func)
,这与

$(function() { func(); });
i、 e.它等待DOM准备就绪,因此在上面的示例中,
$。当
等待加载所有脚本时,等待DOM准备就绪,因为$。延迟的调用在DOM准备就绪回调中解析


对于更通用的用途,一个方便的函数 可以按如下方式创建接受任何脚本数组的实用程序函数:

$.getMultiScripts = function(arr, path) {
    var _arr = $.map(arr, function(scr) {
        return $.getScript( (path||"") + scr );
    });
        
    _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
});
其中,路径将作为所有脚本的前缀,并且也是可选的,这意味着如果数组包含完整URL,那么其中一个也可以这样做,并将路径一起省略

$.getMultiScripts(script_arr).done(function() { ...

论点、错误等。 另请注意,
done
回调将包含许多与传入脚本匹配的参数,每个参数表示一个包含响应的数组

$.getMultiScripts(script_arr).done(function(response1, response2, response3) { ...
其中每个数组将包含类似于
[加载的文件的内容、状态、xhr\u对象]
的内容。 我们通常不需要访问这些参数,因为脚本将自动加载,而且大多数情况下,
done
回调是我们真正想要知道所有脚本都已加载的全部,我只是为了完整性而添加它,对于少数需要访问加载文件中的实际文本的情况,或者需要访问每个XHR对象或类似对象时

此外,如果任何脚本加载失败,将调用失败处理程序,并且不会加载后续脚本

$.getMultiScripts(script_arr).done(function() {
     // all done
}).fail(function(error) {
     // one or more scripts failed to load
}).always(function() {
     // always called, both on success and error
});

在前一个脚本的回调中加载以下所需脚本,如下所示:

$.getScript('scripta.js', function()
{
   $.getScript('scriptb.js', function()
   {
       // run script that depends on scripta.js and scriptb.js
   });
});

我在多脚本加载方面遇到了很多问题,其中一个问题是(至少在Chrome中)在通过Ajax成功加载后,同一个域热加载的脚本没有实际运行,而跨域加载的效果非常好!:(

原始问题的选定答案不可靠

经过多次迭代之后,这里是我对getScript的最终答案,我将按照特定的严格顺序异步加载多个脚本,使用每个脚本加载的回调选项和完成时的整体回调,并在jQuery 2.1+和Chrome、Firefox以及被抛弃的Internet Explorer的现代版本中进行测试

我的测试用例是为THREE.JS webGL渲染加载文件,然后在三个全局文件可用时启动渲染脚本,使用传递给onComplete的匿名函数调用的间隔检查

原型函数(getScripts)

function getScripts( scripts, onScript, onComplete )
{
    this.async = true;
    this.cache = false;
    this.data = null;
    this.complete = function () { $.scriptHandler.loaded(); };
    this.scripts = scripts;
    this.onScript = onScript;
    this.onComplete = onComplete;
    this.total = scripts.length;
    this.progress = 0;
};

getScripts.prototype.fetch = function() {
    $.scriptHandler = this;
    var src = this.scripts[ this.progress ];
    console.log('%cFetching %s','color:#ffbc2e;', src);

    $.ajax({
        crossDomain:true,
        async:this.async,
        cache:this.cache,
        type:'GET',
        url: src,
        data:this.data,
        statusCode: {
            200: this.complete
        },
        dataType:'script'
    });
};

getScripts.prototype.loaded = function () {
    this.progress++;
    if( this.progress >= this.total ) {
        if(this.onComplete) this.onComplete();
    } else {
        this.fetch();
    };
    if(this.onScript) this.onScript();
};
如何使用

function getScripts( scripts, onScript, onComplete )
{
    this.async = true;
    this.cache = false;
    this.data = null;
    this.complete = function () { $.scriptHandler.loaded(); };
    this.scripts = scripts;
    this.onScript = onScript;
    this.onComplete = onComplete;
    this.total = scripts.length;
    this.progress = 0;
};

getScripts.prototype.fetch = function() {
    $.scriptHandler = this;
    var src = this.scripts[ this.progress ];
    console.log('%cFetching %s','color:#ffbc2e;', src);

    $.ajax({
        crossDomain:true,
        async:this.async,
        cache:this.cache,
        type:'GET',
        url: src,
        data:this.data,
        statusCode: {
            200: this.complete
        },
        dataType:'script'
    });
};

getScripts.prototype.loaded = function () {
    this.progress++;
    if( this.progress >= this.total ) {
        if(this.onComplete) this.onComplete();
    } else {
        this.fetch();
    };
    if(this.onScript) this.onScript();
};
var scripts = new getScripts(
    ['script1.js','script2.js','script.js'],
    function() {
        /* Optional - Executed each time a script has loaded (Use for Progress updates?) */
    },
    function () {
        /* Optional - Executed when the entire list of scripts has been loaded */
    }
);
scripts.fetch();
该函数与我发现的使用延迟(现在不推荐?)的函数一样,在我的试用中,何时、成功和完成不是100%可靠的!?,因此该函数和statusCode的使用就是一个例子


如果愿意,您可能需要添加错误/失败处理行为。

以上Andrew Marc Newton综合答案的较短版本。此答案不检查状态代码是否成功,您应该这样做以避免未定义的UI行为

这是一个恼人的系统,我可以保证jQuery,但没有其他包含,所以我想要一个足够短的技术,如果强制进入外部脚本,就不会被转移到外部脚本中(通过将索引0传递到第一个“递归”调用,可以使它更短,但风格习惯的力量让我添加了糖)

我还将依赖项列表分配给一个模块名,因此该块可以包含在需要“module1”的任何地方,脚本和依赖项初始化只包含/运行一次(您可以在回调中记录
索引
,并查看一组有序的AJAX请求运行)


有一个插件扩展了jQuery的getScript方法。允许异步和同步加载,并使用jQuery的缓存机制。完全公开,我写了这篇文章。如果你找到更好的方法,请随意贡献


我实现了一个简单的函数来并行加载多个脚本:

作用 用法
您可以使用
$。当使用
-方法时,请尝试以下函数:

function loadScripts(scripts) {
  scripts.forEach(function (item, i) {
    item = $.getScript(item);
  });
  return $.when.apply($, scripts);
}
此函数的使用方式如下:

loadScripts(['path/to/script-a.js', 'path/to/script-b.js']).done(function (respA, respB) {
    // both scripts are loaded; do something funny
});
这是使用承诺的方法,开销最小。

逐个加载n个脚本(例如,如果第二个文件需要第一个脚本,则很有用):


此函数将确保在完全加载依赖项文件后加载文件。您只需按顺序提供文件,并记住对其他文件的依赖项

function loadFiles(files, fn) {
    if (!files.length) {
        files = [];
    }
    var head = document.head || document.getElementsByTagName('head')[0];

    function loadFile(index) {
        if (files.length > index) {
            var fileref = document.createElement('script');
            fileref.setAttribute("type", "text/javascript");
            fileref.setAttribute("src", files[index]);
            head.appendChild(fileref);
            index = index + 1;
            // Used to call a callback function
            fileref.onload = function () {
                loadFile(index);
            }
        } else if(fn){
            fn();
        }
    }
    loadFile(0);
}
回答得很好,阿德内奥

(function self(a,cb,i){
    i = i || 0; 
    cb = cb || function(){};    
    if(i==a.length)return cb();
    $.getScript(a[i++],self.bind(0,a,cb,i));                    
})(['list','of','script','urls'],function(){console.log('done')});
function loadFiles(files, fn) {
    if (!files.length) {
        files = [];
    }
    var head = document.head || document.getElementsByTagName('head')[0];

    function loadFile(index) {
        if (files.length > index) {
            var fileref = document.createElement('script');
            fileref.setAttribute("type", "text/javascript");
            fileref.setAttribute("src", files[index]);
            head.appendChild(fileref);
            index = index + 1;
            // Used to call a callback function
            fileref.onload = function () {
                loadFile(index);
            }
        } else if(fn){
            fn();
        }
    }
    loadFile(0);
}
    function loadMultipleScripts(scripts, callback){
        var array = [];

        scripts.forEach(function(script){
            array.push($.getScript( script ))
        });

        array.push($.Deferred(function( deferred ){
                    $( deferred.resolve );
                }));

        $.when.apply($, array).done(function(){
                if (callback){
                    callback();
                }
            });
    }
// Usage
//$.getMultiResources(['script-1.js','style-1.css'], 'assets/somePath/')
//  .done(function () {})
//  .fail(function (error) {})
//  .always(function () {});

(function ($) {
  $.getMultiResources = function (arr, pathOptional, cache) {
    cache = (typeof cache === 'undefined') ? true : cache;
    var _arr = $.map(arr, function (src) {
      var srcpath = (pathOptional || '') + src;
      if (/.css$/i.test(srcpath)) {
        return $.ajax({
          type: 'GET',
          url: srcpath,
          dataType: 'text',
          cache: cache,
          success: function () {
            $('<link>', {
              rel: 'stylesheet',
              type: 'text/css',
              'href': srcpath
            }).appendTo('head');
          }
        });

      } else {
        return $.ajax({
          type: 'GET',
          url: srcpath,
          dataType: 'script',
          cache: cache
        });
      }
    });
    //
    _arr.push($.Deferred(function (deferred) {
      $(deferred.resolve);
    }));
    //
    return $.when.apply($, _arr);
  };
})(jQuery);
function getScripts(scripts) {
    var prArr = [];
    scripts.forEach(function(script) { 
        (function(script){
            prArr .push(new Promise(function(resolve){
                $.getScript(script, function () {
                    resolve();
                });
            }));
        })(script);
    });
    return Promise.all(prArr, function(){
        return true;
    });
}
var jsarr = ['script1.js','script2.js'];
getScripts(jsarr).then(function(){
...
});
var scriptsToLoad = [
   "script1.js", 
   "script2.js",
   "script3.js",
]; 
    
scriptsToLoad.forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.body.appendChild(script);
});
function loadScripts(urls, path) {
    return new Promise(function(resolve) {
        urls.forEach(function(src, i) {

            let script = document.createElement('script');        
            script.type = 'text/javascript';
            script.src = (path || "") + src;
            script.async = false;

            // If last script, bind the callback event to resolve
            if(i == urls.length-1) {                    
                // Multiple binding for browser compatibility
                script.onreadystatechange = resolve;
                script.onload = resolve;
            }

            // Fire the loading
            document.body.appendChild(script);
        });
    });
}
let JSDependencies = ["jquery.js",
                      "LibraryNeedingJquery.js",
                      "ParametersNeedingLibrary.js"];

loadScripts(JSDependencies,'JavaScript/').then(taskNeedingParameters);
var queue = ['url/links/go/here'];

ProcessScripts(function() { // All done do what ever you want

}, 0);

function ProcessScripts(cb, index) {
    getScript(queue[index], function() {
        index++;
        if (index === queue.length) { // Reached the end
            cb();
        } else {
            return ProcessScripts(cb, index);
        }
    });
}

function getScript(script, callback) {
    $.getScript(script, function() {
        callback();
    });
}
$.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
});