我有一个带有以下代码的js文件,该文件包含在我所有html页面的head部分中。
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等等。
为了演示,假设我有三个js文件:file1.js,file2.js和file3.js。最初只有file1.js包含在我的html页面中。
在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,而file2.js依赖于file3.js,这意味着file1.js依赖于file2.js和file3.js。在执行file1.js中的funMath()之前,如何确保加载file2.js和file3.js?
答案 0 :(得分:1)
一旦你的load
被加载就会触发一个事件<script src="...">
(因为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);
NB一旦不是关于学习JS而是实际产品任务,你最好先了解一下加载器和捆绑器的世界。比如requireJS或webpack(它们来自不同的世界,但应该与您当前的需求相似)。
是的,webpack以第一种方式创建单个捆绑包,但您可以将其调整为将整个代码库拆分为一旦需要就动态加载的块。