index.html
<script src='a.js'>
b.func();
a.js
var oHead = document.getElementsByTagName('head')[0];
var oScript = document.createElement('script');
oScript.setAttribute('src','b.js');
oScript.setAttribute('type','text/javascript');
oHead.appendChild(oScript);
b.js
var B = function (){
}
B.prototype.func = function(){
alert('call b func')
}
var b = new B();
如上代码所述,我希望在index.html中通过a.js来动态的加载b.js,并调用b.js中提供的b.func()
方法,但是在a.js加载b.js时这是异步的,也就是b.js还未加载完成就执行到了index.html中的b.func()
,导致程序出错。有没有办法在a.js加载b.js时阻塞之后的JS执行,直到b.js加载完成呢?要求不能修改index.html的代码,因此不能把调用b.func()
的语句放入b.js的onload中去
同楼上
看了楼主的情景:
回调不合适 ,因为b.func()的调用不是在a.js中完成,实际上这个问题出现的场景是a.js是由我编写的一个sdk,sdk中去动态加载另一个js文件,index.html才是sdk的实际使用者,他需要使用b.js中的内容
觉得这样的SDK设计的使用方式是不合理的。竟然你的sdk种需要异步加载其他代码,那么在你的sdk种一定要提供一个机制,回调或者事件来告诉使用者代码都加载完了,他可以安全的使用sdk的方法了。就像是document ready一样,你需要有个sdk ready
使用 requirejs 一个异步加载JS,模块化代码的框架,非常NICE。
重新理解题主思路后,修正如下:
首先,阻塞的路子不对,应该回调。这个思路不变。
然后,靠事件把这个回调解决
a.js
var oHead = document.getElementsByTagName('head')[0];
var oScript = document.createElement('script');
oScript.setAttribute('src','b.js');
oScript.setAttribute('type','text/javascript');
oScript.onload = function(){
window.dispatchEvent(new Event('b-loaded'));
};
oHead.appendChild(oScript);
index.html
<script src='a.js'></script>
<script>
window.addEventListener('b-loaded', function(){
b.func();
}, false);
</script>
楼主的意思大概是:a.js属于一个loader,b.js属于扩展插件。a.js只负责将b.js之类的插件按照合理的依赖关系引入到页面中。
其实即使在a.js中用回调确保b.js加载成功,但是如果存在多个插件之间有依赖关系时,就会形成多层的回调嵌套。
楼主你可以按照这个思路,a.js作为loader,它负责处理各个插件的依赖关系和加载顺序,然后把处理js文件加载顺序的功能独立出来。
按照CommonJS中的处理方法,如果插件本身不严格声明依赖关系的话,就需要用labjs来确保加载顺序,推荐楼主使用LabJS(http://labjs.com/documentation.php)
// a.js
$LAB
.script('b.js').wait() // 通过wait的调用来确保b.js加载完成
...
看看这种方法能否满足楼主的需要。
回调,或者用 document.write 加载
回调比较合适