问题描述
我正在寻找一个优雅,高效的解决我的问题:我有这个webapp与许多组件;
一个主要组件包括许多随时间增长/增长的添加。
这个主要组件有一个功能,其中在实际执行它应该是做,它触发事件beforedo,以便插件可以听。
dostg:function(){
$ doc.trigger( 'beforedo');
//做东西,但事件后由插件处理?
}
在插件代码中
$ doc.on('beforedo',function(e){
// do before addon stuff
}
现在在做事情之前可能会涉及ajax请求或任何需要一些处理时间的东西。
我可以在ajax请求上增加一个计数器,等待它为零,但我想要的是一个解决方案,只是等待所有处理程序完成他们的工作(因此这将工作无论在这些插件处理程序中做了什么)。
有没有一些奇迹解决方案来做到这一点,或者我不得不忘记事件在这种情况下,另一种方式(数组功能迭代,将新功能推送到数组中的插件)?
感谢您的专业知识!
----编辑以下BOUNTY
道歉给@xbonez& @Sergiu Paraschiv,我应该用我现在使用的解决方案编辑问题 before 提供赏金(解决方案我不完全满意,因此赏金)。
/ app
var $ doc = $(document.body);
//组件
$ doc.on({
wait:function(e){++ $ doc.component.handleinprogress;},
addonready:function(){
- $ doc.component.handleinprogress;
if($ doc.component.handleinprogress == 0)$ doc.trigger('readyfordo');
},
readyfordo:function(){
//在事件处理后的事情由插件
}
});
$ doc.component = {
handleinprogress:0,
dostg:function(){
$ doc.component.handleinprogress = 0;
$ doc.trigger('beforedo');
}
};
//在组件插件文件中
$ doc.on('beforedo',function(e){
$ doc.trigger等待');
//做插件
$ doc.trigger(addonready);
}
我不满意这个解决方案,因为即使我不需要在addon beforedo之前做任何事情,我仍然需要添加处理程序来触发addonready(在至少一个addon - >所以我无法从组件中添加/删除addon,而不用担心readyfordo是否被触发,否则我不得不在每个插件中包含处理程序 - 大多数是-75% - 没有任何东西)。
要等待所有处理程序在执行一些代码之前完成,您应该使用jQuery的 deferred
API你可以这样做:
$。when($。ajax(/ page1.php),$。 ajax(/ page2.php))。done(function(a1,a2){
//只在两个ajax调用完成后才执行
});
另外jQuery的允许您传递额外的参数。传递一个函数,这将是回调函数。
你的最终代码应该是这样的:
$ doc.trigger('beforedo',function(){
//这里只有在事件处理完成后才执行
});
$ doc.on('beforedo',function(e,callback){
// do before addon stuff
$ .when($。ajax( /page1.php),$ .ajax(/ page2.php))。done(function(a1,a2){
//此时,所有AJAX调用都已完成
//调用回调函数
callback();
});
}
如果需要,当您调用 callback()
时,您甚至可以传递任何可能需要作为参数传递的结果,因此更改函数签名在 .trigger()
通话中。
扩展我在下面留下的评论,你可以有一个共同点如果你喜欢,装载器功能:
$。when(load(page1),load(page2)) (function(){
// ...
});
函数加载(文件){
//返回$ .ajax promise
return $ .ajax(file);
}
请参阅:
I'm looking for an elegant, efficient solution to my problem :
I have this webapp with many components;
One main component include many additions that will grow/evolve with time.
This main component has a function in which before actually doing what it is supposed to do, it is triggering an event beforedo so that the addons can listen to.
dostg : function () {
$doc.trigger('beforedo');
//do stuff but after event is handled by the addons ?
}
In the addons codes
$doc.on('beforedo',function(e) {
//do before addon stuff
}
Now those before doing stuff may involve ajax request or anything that would take some processing time.
I could increment a counter on ajax requests and wait it is down to nil, but what I'd like is a solution that would just wait for all handlers to finish their job (and therefore that'd work whatever is being done in those addons handlers).
Is there some miracle solution to do this or I have to forget about event in this situation and go another way (array of function to iterate, addons pushing new function into array) ?
Thanks for your expertise!
-------EDIT FOLLOWING THE BOUNTY
Apologize to @xbonez & @Sergiu Paraschiv , I should have edit the question with the solution I'm using now before offering the bounty (solution I'm not totally satisfied with, hence the bounty).
//app
var $doc = $(document.body);
//component
$doc.on({
wait: function (e) { ++$doc.component.handleinprogress; },
addonready: function () {
--$doc.component.handleinprogress;
if ($doc.component.handleinprogress==0) $doc.trigger('readyfordo');
},
readyfordo: function () {
//do stuff after event has been handled by the addons
}
});
$doc.component = {
handleinprogress: 0,
dostg: function () {
$doc.component.handleinprogress = 0;
$doc.trigger('beforedo');
}
};
//in component addon files
$doc.on('beforedo', function (e) {
$doc.trigger('wait');
//do addon stuff
$doc.trigger("addonready");
}
I'm not satisfied with this solution because even if I don't need to do stuff in the addon beforedo I still have to add the handler to trigger addonready (in at least one of the addon -> so either i lose flexibility to add/remove addon from the component without worrying whether readyfordo get triggered, either I have to include the handler in every addon - mostly -75%- for nothing).
解决方案 To wait for all handlers to finish before executing some code, you should use jQuery's deferred
API. You can do something like this:
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
// only executes after both ajax calls have completed
});
Further, jQuery's trigger
allows you to pass extra params. Pass in a function which will be the callback function.
Your final code should look something like this:
$doc.trigger('beforedo', function() {
// anything here only executes after the event has been handled
});
$doc.on('beforedo',function(e, callback) {
//do before addon stuff
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
// at this point, all your AJAX calls have completed
// call the callback function
callback();
});
}
If need be, when you call callback()
you can even pass in any result you might need to pass as an argument. Accordingly, change the function signature in your .trigger()
call too.
Expanding on the comment I left below, you can have a common loader function if you like:
$.when(load("page1"), load("page2")).done(function(){
// ...
});
function load(file) {
// return the $.ajax promise
return $.ajax(file);
}
See:
jQuery deferred
jQuery.when()
jQuery.trigger
这篇关于等待处理事件以继续执行已触发事件的功能。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!