当另一个函数存在时执行javascript
我在一个web环境中编写了两个脚本,在这个环境中,我无法控制加载它们的顺序。假设这两个脚本被称为当另一个函数存在时执行javascript,javascript,jquery,Javascript,Jquery,我在一个web环境中编写了两个脚本,在这个环境中,我无法控制加载它们的顺序。假设这两个脚本被称为MyUtil和DoSomething MyUtil包含我将使用window.MyUtil=MyUtil绑定到window对象的实用程序。然后我将从DoSomething中调用myUtil的方法 如果先加载MyUtil,一切都会正常工作。如果是第二次加载,window.myUtil将是未定义的 如何修改DoSomething(和/或MyUtil)中的代码,以等待window.MyUtil存在,然后DoS
MyUtil
和DoSomething
MyUtil
包含我将使用window.MyUtil=MyUtil
绑定到window
对象的实用程序。然后我将从DoSomething
中调用myUtil
的方法
如果先加载MyUtil
,一切都会正常工作。如果是第二次加载,window.myUtil
将是未定义的
如何修改DoSomething
(和/或MyUtil)中的代码,以等待window.MyUtil
存在,然后DoSomething
执行其代码
注意:我正在使用jquery1.2.3 您喜欢这项工作吗
function function1(callback){
var params={
type: "POST",
url: "./ajax/doSomethingSlow.php",
data: "",
success: function(msg){
callback(msg);
},
error: function(){
callback('');
}
};
var result=$.ajax(params).responseText;
}
function1(function(){
//call function2 here:
function2();
});
等待myUtil可用
您可以使用window.setInterval()
将计时器设置为等待window.myUtil
设置完毕后再尝试使用它
例子
例如:
模拟在加载所需脚本后添加window.myUtil
的情况:
window.setTimeout((function(){
window.myUtil = {
utility: function(){ alert('utility has great utility!'); }
};
}), 5000);
在页面的其他位置:
// Declaration of function that requires window.myUtil
var doSomething = function() {
window.myUtil.utility();
}
/*
* Timer that checks for myUtil every 100 milliseconds
* When myUtil does exist, the timer is cleared, and doSomething() is called.
*
* Alternatively, one could put this timer inside doSomething().
*/
var timer = window.setInterval(function(){
if (window.myUtil != undefined) {
window.clearInterval(timer);
doSomething();
}
}, 100);
您可以使用动态加载来加载javascript,但是如果您也无法控制脚本的位置,那么我认为这也可能是一个问题 无论如何,在“做某事”中,您基本上可以通过ajax下拉脚本或使用
文档。编写以插入新的脚本标记:
function doSomething(){
if(!window.myUtil){
// method of choice for loading script
doSomething();
}
else {
// normal logic for doSomething
}
}
然后在您的util中,您需要修改它,以便它在分配它之前检查现有的window.myUtil
。它的外观取决于我的utl如何操作——它是对象实例还是jsut是静态函数的文本集合
有关实际加载脚本源代码的一些方法,请参阅。您可以测试window.myUtil
,如果它未定义,请处理它。这可能意味着使用setInterval
或setTimeout
来轮询它的存在,当找到它时,继续
您也可以等待加载事件,但那可能太晚了。您可以使用
最后我在MyUtil中使用了一个触发器,我在DoSomething中检查它。这很有效
在MyUtil的末尾,我添加了:
$(document).trigger('myUtilLoaded');
if (!(window.myUtil))
{
$(document).bind('myUtilLoaded', function(e) {
doSomething();
});
}
else
{
doSomething();
}
在DoSomething的末尾,我补充道:
$(document).trigger('myUtilLoaded');
if (!(window.myUtil))
{
$(document).bind('myUtilLoaded', function(e) {
doSomething();
});
}
else
{
doSomething();
}
jQuery.Deferred
对象提供了一种非常优雅的方法来实现这一点(我知道您没有使用jQuery 1.5:我只是给您一个升级;-)的理由)
:
假设我们有两个脚本合作,如下所示:
// defines utilities
var util = util || { loaded: $.Deferred() };
(function(){
$.extend(util, {
msg: "Hello!"
});
util.loaded.resolve();
})();
。。。以及:
// uses them
var util = util || { loaded: $.Deferred() };
util.loaded.then(function(){
alert(util.msg);
});
。。。在第一个脚本有机会定义它的实用程序后,无论它们加载的顺序如何,警报都会触发。这比setTimeout
和基于事件的方法具有优势,因为它更容易拥有多个依赖项(使用$。当
时),不使用轮询,并且您不必担心显式处理加载顺序
唯一有点恶心的是,所有模块都必须包括:
var util = util || { loaded: $.Deferred() };
。。。和$.extend()
来确保它们使用相同的延迟 虽然从技术角度来看,这可能可行,但我真的不想使用人工计时游戏来实现。他不知道何时会添加“myUtil”。是的,$(document).ready()
是我尝试的第一件事,但没有成功。我想他只是不确定原始HTML中包含的脚本文件的顺序。因此,等待load事件应该保证所有脚本文件都已下载。如果脚本文件是动态加载的,这将不起作用。我相信脚本文件是动态加载的。如果首先加载myutil,将触发myUtilLoaded,但不会绑定任何内容it@james说得好。更新以首先检查是否存在myUtil
。您有权访问动态加载myUtil
的代码吗?如果是这样,您可以使用jQuery.getScript()
加载它,然后在成功回调中调用DoSomething
。@Rob我可以走这条路,但在我所处的环境中,我认为这将为我带来更多的长期维护。+1这非常好。我使用的是RSVP,只是在我的模块中插入了一个deferred,而不必使用$.extend。@Aaron您能解释一下使用自调用函数和$.extend()
vsutil.msg=“Hello!”的优点吗;util.loaded.resolve()代码>