最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Best way to asynchronously load external js files via Promises - Stack Overflow

programmeradmin1浏览0评论

I am building a website that uses some external js files. I load the files via the code below, but I am not sure how to proceed if one or more of the files fails downloading. Should I just keep requesting them until all of them download? Is it better to do a separate onload event for each file? How would I know which file has failed loading and needs to be requested again?

var filesToLoad = [".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);
    };
}

I am building a website that uses some external js files. I load the files via the code below, but I am not sure how to proceed if one or more of the files fails downloading. Should I just keep requesting them until all of them download? Is it better to do a separate onload event for each file? How would I know which file has failed loading and needs to be requested again?

var filesToLoad = ["https://maxcdn.bootstrapcdn./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);
    };
}
Share Improve this question edited Aug 30, 2015 at 15:30 Autumn asked Aug 29, 2015 at 22:02 AutumnAutumn 2233 silver badges15 bronze badges 3
  • Are those scripts required for your application to work? If that's the case, what other option do you have? – Joaquín O Commented Aug 29, 2015 at 22:06
  • In my opinion you have to create new instance for each file. The benifite of this will be that if any file will fail to load then in its error function you can reload it only. – Eshu Commented Aug 29, 2015 at 22:19
  • @Joanquin O Should I restructure my code to have it so every time reject(script) is hit, a new promise is made and it goes in a loop like that until all promises are resolved? – Autumn Commented Aug 29, 2015 at 22:24
Add a ment  | 

2 Answers 2

Reset to default 5

Well, there is an official API for it called "dynamic import", I remend that you use it or shim it (with something like SystemJS or with a tool that supports it like webpack).

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

If you want to load multiple files you can also use it:

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

May be this will help you.

var filesToLoad = ["https://maxcdn.bootstrapcdn./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);
    };
}
发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>