[英]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.