通过Promises异步加载外部js文件的最佳方法

时间:2015-08-29 22:03:00

标签: javascript jquery promise

我正在构建一个使用一些外部js文件的网站。我通过下面的代码加载文件,但如果一个或多个文件下载失败,我不知道如何继续。我应该继续请求他们直到所有人下载吗?为每个文件执行单独的onload事件会更好吗?我怎么知道哪个文件加载失败并需要再次请求?

var filesToLoad = ["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"];

var loader = new ScriptLoader();
filesToLoad.forEach(function(file) {
    loader.add(file);
});

loader.loaded(function(failedCallbackF) {
    console.log("Error.");
    //Try getting the files again??
});

function ScriptLoader() {
    var promises = [];

    this.add = function(url) {
        var promise = new Promise(function(resolve, reject) {

            var script = document.createElement('script');
            script.src = url;

            script.addEventListener('load', function() {
                resolve(script);
            }, false);

            script.addEventListener('error', function() {
                reject(script);
                console.log('was rej');
            }, false);

            document.body.appendChild(script);
        });

        promises.push(promise);
    };

    this.loaded = function(callbackOnFailed) {
        Promise.all(promises).then(function(result1) {
            console.log('Script loaded from:', result1);
        }, callbackOnFailed);
    };
}

2 个答案:

答案 0 :(得分:5)

嗯,有一个名为"dynamic import"的官方API,我建议您使用它或者使用它(使用类似SystemJS或支持它的工具,如webpack)。

import("yourScriptFile.js").then(function(){
   // script loaded.
});

如果您想加载多个文件,也可以使用它:

Promise.all(["url1", "url2"].map(System.import)).then(function(){
    // loaded all here
});

答案 1 :(得分:3)

可能会对你有帮助。

var filesToLoad = ["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"];   

filesToLoad.forEach(function(file) {
    var loader = new ScriptLoader();
    loader.add(file)
    loader.loaded(function(failedCallbackF) {
        console.log("Error.");
        //reload this file
    });

});

function ScriptLoader() {
    var promises = [];

    this.add = function(url) {
        var promise = new Promise(function(resolve, reject) {

            var script = document.createElement('script');
            script.src = url;

            script.addEventListener('load', function() {
                resolve(script);
            }, false);

            script.addEventListener('error', function() {
                reject(script);
                console.log('was rej');
            }, false);

            document.body.appendChild(script);
        });

        promises.push(promise);
    };

    this.loaded = function(callbackOnFailed) {
        Promise.all(promises).then(function(result1) {
            console.log('Script loaded from:', result1);
        }, callbackOnFailed);
    };
}