等待处理事件以继续执行触发事件的功能.

mik*_*kun 6 javascript jquery events

我正在寻找一个优雅,高效的解决方案来解决我的问题:

我有这个带有许多组件的webapp;

一个主要组成部分包括许多随时间增长/发展的新增内容.

这个主要组件有一个功能,在实际执行它应该做的事情之前,它会触发事件,然后插件可以监听.

dostg : function () {
   $doc.trigger('beforedo');

   //do stuff but after event is handled by the addons ?

}
Run Code Online (Sandbox Code Playgroud)

在插件代码中

$doc.on('beforedo',function(e) {
   //do before addon stuff
}
Run Code Online (Sandbox Code Playgroud)

现在那些做事之前可能涉及ajax请求或任何需要一些处理时间的事情.

我可以在ajax请求上增加一个计数器并等待它降到零,但是我想要的是一个等待所有处理程序完成工作的解决方案(因此,无论在这些插件中做什么,它都能正常工作)处理程序).

是否有一些奇迹解决方案来做到这一点,或者我必须忘记在这种情况下的事件,并采取另一种方式(迭代的函数数组,插件将新函数推入数组)?

感谢您的专业知识!

-------编辑后的编辑

向@xbonez和@Sergiu Paraschiv道歉,提供赏金之前,我应该用我现在使用的解决方案编辑问题(解决方案我并不完全满意,因此是赏金).

//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");
}
Run Code Online (Sandbox Code Playgroud)

我对这个解决方案不满意,因为即使我不需要在插件中执行操作,我仍然需要添加处理程序来触发addonready(至少在其中一个插件中 - >所以要么我失去了添加的灵活性/从组件​​中删除插件而不用担心readyfordo是否被触发,要么我必须在每个插件中包含处理程序 - 大多数是-75% - 什么也没有.

xbo*_*nez 7

要在执行某些代码之前等待所有处理程序完成,您应该使用jQuery的deferredAPI.你可以这样做:

$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
  // only executes after both ajax calls have completed
});
Run Code Online (Sandbox Code Playgroud)

此外,jQuery trigger允许您传递额外的参数.传递一个将成为回调函数的函数.

您的最终代码应如下所示:

$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();
  });
}
Run Code Online (Sandbox Code Playgroud)

如果需要,当你打电话时,callback()你甚至可以传递任何结果,你可能需要传递作为参数.因此,.trigger()也要更改通话中的功能签名.

扩展我留下的评论,如果您愿意,可以使用常用的加载器功能:

$.when(load("page1"), load("page2")).done(function(){
 // ...
});

function load(file) {
  // return the $.ajax promise
  return $.ajax(file);
}
Run Code Online (Sandbox Code Playgroud)

看到:

jQuery推迟了
jQuery.when()
jQuery.trigger