首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何等待动态加载的脚本在javascript中完全执行?

如何等待动态加载的脚本在javascript中完全执行?
EN

Stack Overflow用户
提问于 2018-11-09 06:29:50
回答 2查看 413关注 0票数 0

在javascript中,我加载了几个脚本,然后要运行一个函数。问题是,我的承诺言之过早。它在下载每个文件之后运行,但我需要等待它们全部添加到DOM中,并完全执行。

代码语言:javascript
复制
(function() {

    function getFile(path) {
        return $.get(path, function (data) {
            $("body").append(data);
        });
    }

    $.when.apply($, [
        // load all the individual components
        "components/once/ti-snackbar/ti-snackbar.html",
        "components/once/ti-not-supported/ti-not-supported.html",
        "components/once/ti-drawer/ti-drawer.html",
        "components/widgets/ti-company-table-row/ti-company-table-row.html",
        "components/widgets/ti-chip-set/ti-chip-set.html",
        "components/widgets/ti-list/ti-list.html",
        "components/widgets/ti-user-card/ti-user-card.html",
        "components/widgets/ti-tabs/ti-tabs.html",
        "components/widgets/ti-data-table/ti-data-table.html",
        "components/forms/ti-new-company-form/ti-new-company-form.html",
        "components/forms/ti-edit-company-form/ti-edit-company-form.html",
        "components/pages/ti-page-inquire/ti-page-inquire.html",
        "components/pages/ti-page-companies/ti-page-companies.html",
        "components/pages/ti-page-report/ti-page-report.html",
        "components/pages/ti-page-admins/ti-page-admins.html",
        "components/pages/ti-page-contacts/ti-page-contacts.html",
        "components/pages/ti-page-policy/ti-page-policy.html",
        "components/pages/ti-page-manual/ti-page-manual.html",
        "components/pages/ti-page-404/ti-page-404.html",
        "components/tabs/ti-tab-name/ti-tab-name.html",
        "components/tabs/ti-tab-tags/ti-tab-tags.html",
        "components/tabs/ti-tab-status/ti-tab-status.html",   
        "components/tabs/ti-tab-restriction/ti-tab-restriction.html",     
        "components/tabs/ti-tab-other/ti-tab-other.html"   
    ].map(getFile)).then(function() {
        // render the full app after all components load
        getFile("components/once/ti-app/ti-app.html");
    });
})();

我怎么才能修好它?

注意:每个html文件都有一个<script><template>

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-09 16:55:04

我看到了这段代码可能存在的几个问题:

  1. 您不会强迫您的$.get()调用按顺序完成,这样您就可以得到一个可变的完成顺序,并且事情可能会以不同的顺序附加到主体中(如果这很重要的话)。
  2. 你使用的是承诺和回调的组合,这会使事情很难准确排序。一般来说,不要把承诺和回调混为一谈。如果您在一个地方有承诺,可以在任何地方使用它们(必要时将回调转换为承诺)。
  3. 你说你“想在后面运行一个函数”,但是你没有解释你要把这个函数放在哪里。为了等待所有的承诺,它必须在.then()处理程序中。

下面是一个清除这些问题的实现:

代码语言:javascript
复制
(function() {

    function getFile(path) {
        return $.get(path);
    }

    function append(data) {
        $("body").append(data);
    }

    var resources = [
        "components/once/ti-snackbar/ti-snackbar.html",
        "components/once/ti-not-supported/ti-not-supported.html",
        "components/once/ti-drawer/ti-drawer.html",
        "components/widgets/ti-company-table-row/ti-company-table-row.html",
        "components/widgets/ti-chip-set/ti-chip-set.html",
        "components/widgets/ti-list/ti-list.html",
        "components/widgets/ti-user-card/ti-user-card.html",
        "components/widgets/ti-tabs/ti-tabs.html",
        "components/widgets/ti-data-table/ti-data-table.html",
        "components/forms/ti-new-company-form/ti-new-company-form.html",
        "components/forms/ti-edit-company-form/ti-edit-company-form.html",
        "components/pages/ti-page-inquire/ti-page-inquire.html",
        "components/pages/ti-page-companies/ti-page-companies.html",
        "components/pages/ti-page-report/ti-page-report.html",
        "components/pages/ti-page-admins/ti-page-admins.html",
        "components/pages/ti-page-contacts/ti-page-contacts.html",
        "components/pages/ti-page-policy/ti-page-policy.html",
        "components/pages/ti-page-manual/ti-page-manual.html",
        "components/pages/ti-page-404/ti-page-404.html",
        "components/tabs/ti-tab-name/ti-tab-name.html",
        "components/tabs/ti-tab-tags/ti-tab-tags.html",
        "components/tabs/ti-tab-status/ti-tab-status.html",   
        "components/tabs/ti-tab-restriction/ti-tab-restriction.html",     
        "components/tabs/ti-tab-other/ti-tab-other.html"   
    ];

    return Promise.all(resources.map(getFile)).then(function(data) {
        // append all items to the body in order now that they are all retrieved
        data.forEach(append);
    }).then(function() {
        // now that everything else is in place, load and append 
        // the part that uses those scripts and templates
        return getFile("components/once/ti-app/ti-app.html").then(append);
    }).catch(function(err) {
        // handle error here
        console.log(err);
        throw err;    // propagate error
    });
})().then(function() {
    // everything loaded here for code outside the IIFE here to know when it's all done
}).catch(function(err) {
    // error occurred here for code outside the IIFE here to know there was an error
});

最后一个.then().catch()是可选的,如果您想让IIFE之外的代码能够知道事情何时完成或发生错误的话。

事物的修改和推理:

  1. 首先加载所有资源,然后以可预测的顺序追加资源,这允许您具有相互依赖关系或依赖于以前依赖关系的任何脚本初始化。在此之前,并没有明确的命令将您的脚本追加。
  2. 在加载和追加所有其他脚本之前,不会加载和追加ti-app.html
  3. 将脚本数组的声明移到主代码流之外,以提高代码流的可读性。
  4. 附加错误检测
  5. 提供两个地方,你可以知道什么时候完成加载或是否有错误,一个在生活和生活之外(取决于你需要什么)。
票数 1
EN

Stack Overflow用户

发布于 2018-11-09 06:49:36

这可能是有用的:https://css-tricks.com/snippets/javascript/async-script-loader-with-callback/

代码语言:javascript
复制
var Loader = function () { }
Loader.prototype = {
    require: function (scripts, callback) {
        this.loadCount      = 0;
        this.totalRequired  = scripts.length;
        this.callback       = callback;

    for (var i = 0; i < scripts.length; i++) {
        this.writeScript(scripts[i]);
    }
},
loaded: function (evt) {
    this.loadCount++;

    if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call();
},
writeScript: function (src) {
    var self = this;
    var s = document.createElement('script');
    s.type = "text/javascript";
    s.async = true;
    s.src = src;
    s.addEventListener('load', function (e) { self.loaded(e); }, false);
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(s);
}

用法:

代码语言:javascript
复制
var l = new Loader();
l.require([
"example-script-1.js",
"example-script-2.js"], 
function() {
    // Callback
    console.log('All Scripts Loaded');
    // call your other script here
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53220844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档