Как ждать, чтобы динамически загруженные скрипты полностью выполнялись в javascript? - PullRequest
0 голосов
/ 09 ноября 2018

В javascript я загружаю несколько скриптов, а затем хочу запустить функцию после. Проблема в том, что мое обещание выполняется слишком рано. Он запускается после загрузки каждого файла, но мне нужно подождать, пока они все не будут добавлены в DOM и полностью выполнены.

(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>.

Спасибо

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Я вижу несколько возможных проблем с этим кодом:

  1. Вы не заставляете свои вызовы $.get() завершаться, чтобы получить переменный порядок завершения, и вещи могут добавляться к телу в различном порядке (если это имеет значение).

  2. Вы используете сочетание обещаний и обратных вызовов, которые могут затруднить точное определение последовательности вещей. В общем, не смешивайте обещания и обратные вызовы. Если у вас есть обещания в одном месте, используйте их везде (при необходимости преобразуйте обратные вызовы в обещания).

  3. Вы говорите, что «хотите запустить функцию после», но не объясняете, где пытаетесь поместить эту функцию. Чтобы дождаться всех обещаний, он должен быть в обработчике .then().

Вот реализация, которая очищает их:

(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. Укажите два места, которые вы можете знать, когда все будет загружено или если произошла ошибка: одно внутри IIFE и одно за пределами IIFE (в зависимости от того, что вам нужно).

0 голосов
/ 09 ноября 2018

Это может быть полезно: https://css -tricks.com / snippets / javascript / async-script-loader-with-callback /

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);
}

Использование:

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
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...