加载所有脚本后如何获得回调?

时间:2015-12-12 08:30:05

标签: javascript

我如何知道下面代码中加载的所有脚本?

function loadExternalResource(url, type, callback){
    var _css, _script, _document = document;
    if(type === 'css'){
        _css = _document.createElement("link");
        _css.type = 'text/css';
        _css.rel = 'stylesheet';
        _css.href = URL;
        _document.getElementsByTagName("head")[0].appendChild(_css);
    }
    else if(type === "js")
    {
            _script = _document.createElement("script");
            _script.type = "text/javascript";
            _script.src = URL;
            _script.onload = callback;
            _document.getElementsByTagName("head")[0].appendChild(_script);
    }
}

//Loading All Css Here
loadExternalResource('/css/common.css','css');
loadExternalResource('/css/main.css','css');

//Load All Scripts here
loadExternalResource('/js/general.js','js', function(){
    alert('general js loaded');
});
loadExternalResource('/js/validation.js','js', function(){
    alert('validation js loaded');
});
loadExternalResource('/js/core.js','js', function(){
    alert('core js loaded');
});
loadExternalResource('/js/library.js','js', function(){
    alert('library js loaded');
});

在上面的代码中,我收到了每个加载的js文件的回调,但是如何知道这里加载的所有脚本?

2 个答案:

答案 0 :(得分:1)

这是使用promises的想法。一般的想法是,您更改函数loadExternalResource()以返回在加载资源时解析的promise。然后,您可以将任意数量的这些承诺收集到一个数组中,并使用Promise.all()查看所有这些承诺何时完成。为方便起见,我将此功能放入一个名为loadMultipleExternalResources()的主函数中,该函数加载一系列URL。

以下是代码:

function loadExternalResource(url, type){
    return new Promise(function(resolve, reject) {
        var tag;
        if (!type) {
            var match = url.match(/\.([^.]+)$/);
            if (match) {
                type = match[1];
            }
        }
        if (!type) {
            type = "js";       // default to js
        }

        if (type === 'css'){
            tag = document.createElement("link");
            tag.type = 'text/css';
            tag.rel = 'stylesheet';
            tag.href = url;
        }
        else if (type === "js")
        {
            tag = document.createElement("script");
            tag.type = "text/javascript";
            tag.src = url;
        }
        if (tag) {
            tag.onload = function() {resolve(url);};
            tag.onerror = function() {reject(url);};
            document.getElementsByTagName("head")[0].appendChild(tag);
        }
    });
}

function loadMultipleExternalResources(itemsToLoad) {
    var promises = itemsToLoad.map(function(url) {
        return loadExternalResource(url);
    });
    return Promise.all(promises);    
}

//Loading All Css Here
var urls = ['/css/common.css', '/css/main.css', '/js/general.js', '/js/validation.js', '/js/core.js','js', '/js/library.js'];

loadMultipleExternalResources(urls).then(function() {
    // all these resources loaded here
});

或者,使用您的回调方案,您可以手动保留已加载文件数量的计数器:

function loadExternalResource(url, type, callback){
    var tag;

    ++loadExternalResource.cnt;
    if (type === 'css'){
        tag = _document.createElement("link");
        tag.type = 'text/css';
        tag.rel = 'stylesheet';
    }
    else if (type === "js")
    {
        tag = _document.createElement("script");
        tag.type = "text/javascript";
        tag.src = url;
    }
    if (tag) {
        tag.onload = function() {
            --loadExternalResource.cnt;
            callback(loadExternalResource.cnt, url);
        }
        tag.getElementsByTagName("head")[0].appendChild(tag);
    }
}

loadExternalResource.cnt = 0;

//Loading All Css Here
loadExternalResource('/css/common.css','css', checkAllDone);
loadExternalResource('/css/main.css','css', checkAllDone);

//Load All Scripts here
loadExternalResource('/js/general.js','js', checkAllDone);
loadExternalResource('/js/validation.js','js', checkAllDone);
loadExternalResource('/js/core.js','js', checkAllDone);
loadExternalResource('/js/library.js','js', checkAllDone);

function checkAllDone(cnt, url) {
    if (cnt === 0) {
        // all scripts and CSS files loaded now
    }
}

答案 1 :(得分:0)

可以使用jQuery吗?

使用$.when非常简单。您只要

$.when($getScript("file1.js"), 
       $getScript("file2.js"), 
       $getScript("file3.js")).
       done(function(){
          //code here
       }
);