繁体   English   中英

将JS文件包含在javascript中时,如何确保在执行任务之前加载所有JS文件

[英]How to ensure all JS files are loaded before executing a task when including JS files with javascript

我有一个js文件,其中包含以下代码,这些代码包含在我的所有html页面的头部。

myApp.jsLoad = (function () {

    var obj_1 = {
        getScript: jQuery.getScript,

        // Load multiple js files
        getMultipleScripts: function( filesArray, callback ) {
            var // reference declaration & localization
            length = filesArray.length,
            handler = function() { counter++; },
            deferreds = [],
            counter = 0,
            idx = 0;

            for ( ; idx < length; idx++ ) {
                deferreds.push(
                    obj_1.getScript( filesArray[ idx ], handler )
                );
            }

            jQuery.when.apply( null, deferreds ).then(function() {
                callback && callback();
            });
        } ,
        //-----End-----getMultipleScripts----------------



        // Checks if js file is being included for the first time
        // namesp: use a sub-namespace of myApp
        // jsFile: use the full filepath 
        isFirstLoad: function(namesp, jsFilepath) {

            // namesp.firstLoad will be undefined if file hasn't been included before
            var isFirst = namesp.firstLoad === undefined; 

            namesp.firstLoad = false;

            return isFirst;
        } ,
        // ----End-----------isFirstLoad----------------


        // Load js files that have not been loaded before
        // fileList is an object of namespace and filepath
        loadNewScripts:  function(fileList) {

            // RSVP.Promise uses RSVP Promise library
            return new RSVP.Promise(function(fulfill, reject) {
                var filesToLoad = [];
                $.each(fileList, function(index, el) {

                    if (!obj_1.isFirstLoad(el.nameSp, el.jsfile) ) {
                        // if file already included before
                    } else {
                        // This js file hasn't been loaded into page yet
                        // so push into filesToLoad array so we can load them altogether at once 
                        filesToLoad.push(el.jsfile);
                    }
                }); 

                obj_1.getMultipleScripts(filesToLoad, function() {
                    //Do something after all scripts have loaded
                    fulfill('JS files loaded');                 
                });

            }) // RSVP.Promise

        } ,
        //-----End------- loadNewScripts---------------------



    }; // obj_1 
    //-----End------obj_1-------------------

    return obj_1;

}()); 

上面的js文件中值得关注的部分是loadNewScripts 基本上, loadNewScripts作用是,当您传递由名称空间和文件路径组成的对象作为参数时,如果尚未加载这些js文件,它将加载这些文件。

这很有用,因为在我的项目中,我有许多js文件,并且某些js文件依赖于其他js文件。 因此,除了为HTML页面所需的每个js文件添加<script type="text/javascript" src="somefile.js"></script> ,我还可以在HTML页面中添加一个js文件,文件将加载所需的js文件,这些加载的js文件可以加载所需的其他js,依此类推。

为了演示,假设我有三个js文件:file1.js,file2.js和file3.js。 最初,我的html页面中仅包含file1.js。

在file1.js中, myApp.jsLoad.loadNewScripts在执行funMath()之前先加载file2.js:

 myApp = myApp || {};
(function () {
    myApp.f2 = myApp.f2 || {};
    var fileList = [
        {
            nameSp: myApp.f2 ,
            jsfile: 'file2.js'
        }
    ];

    myApp.jsLoad.loadNewScripts(fileList)
    .then(function(loadStatus) { 
        funMath();
    })

    var funMath = function() {
        var a = myApp.f2.getNum();
        alert(a);
    }
}()); 

在file2.js中, myApp.jsLoad.loadNewScripts加载file3.js:

myApp = myApp || {};
(function () {
    myApp.f3 = myApp.f3 || {};
    var fileList = [
        {
            nameSp: myApp.f3 ,
            jsfile: 'file3.js'
        }
    ];

    myApp.jsLoad.loadNewScripts(fileList)
    .then(function(loadStatus) { 
       myApp.f2 = obj;
    })

    var obj = {
        getNum: function() {
             return myApp.f3.getRand();
        }
    };
}()); 

file3.js中的代码:

 myApp = myApp || {}

 myApp.f3 = (function () {

    var obj = {
        getRand: function() {
             return Math.floor(Math.random() * 10); 
        }
    };
    return obj
}()); 

现在在file1.js中,funMath()一直等到file2.js被加载后才执行,但是如何知道是否已加载file3.js?

file1.js依赖于file2.js,而后者又依赖于file3.js,这意味着file1.js同时依赖于file2.js和file3.js。 在执行file1.js中的funMath()之前,如何确保同时加载file2.js和file3.js?

一旦您的<script src="...">load ,就会触发事件加载(并且由于JS是单线程的,因此也意味着它也已执行)

 var body = document.body; var scriptEl = document.createElement('script'); scriptEl.src = 'https://underscorejs.org/underscore-min.js'; scriptEl.addEventListener('load', function() { console.log('Underscore version is ' + _.VERSION); }); body.appendChild(scriptEl); 

注意:一旦不是要学习JS,而是要学习实际的产品任务,那么最好了解一下装载机和捆扎机的世界。 说requireJS或webpack(它们来自不同的领域,但在当前需求范围内应该相似)。

是的,第一种方式的webpack会创建单个捆绑包,但您可以对其进行调整以将整个代码库拆分为块,并在需要时动态加载它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM