我什么时候可以使用JQuery.Callbacks?

我正在寻找新的东西添加到jQuery 1.7,我看到他们现在有jQuery.Callbacks() http://api.jquery.com/jQuery.Callbacks/ 。

该文档向您展示了如何使用jQuery.callbacks(),但没有任何适用的例子,当我想要使用它们。

看来你可以添加/删除callback列表中的callback,你可以做jQuery.callbacks()。fire(args),但是这只是closures了列表中的所有callback。 也许我错过了一些东西,但这似乎并不是很有用。

在我看来,当我第一次看到这个新function的时候,我认为你可以通过键/值对来使用它。 然后,这将提供一个简单的方法来pipe理应用程序中的一个地方的callback函数。 就像是

$.callbacks.add("foo", myFunction); 

然后例如,如果我想在我的函数结束时调用该callback函数,我可以做类似的事情

 $.callbacks().fire("foo", args); 

然而,它看起来并不像你可以触发特定的callback,你只能用给定的参数或者没有任何参数来触发它们。

我看到的最接近的东西是赋予.fire()函数上下文来设置“this”属性的能力

 .fireWith(context, args) 

但这也不是很有帮助。

  1. 我误解了文档吗?

  2. 如果这是所需的function,那么这是有用的一些适用的例子。

扩展@Rocket回答一些并澄清一些混淆:

可能需要使用jQuery的$.Callbacks是多方面的:

  1. 用户在一个函数中有很多代码,并想分解它
  2. 他们把这些信息通过jQuerycallback函数发送出去,然后让他们把代码分解成更好的可处理的代码块。
    所以(例如)如果你看@ Rocket的代码 :

     var clickCallbacks = $.Callbacks(); clickCallbacks.add(function() { //one one function piece //parse and do something on the scope of `this` var c = parseInt(this.text(), 10); this.text(c + 1); }); clickCallbacks.add(function(id) { //add a second non-related function piece //do something with the arguments that were passed $('span', '#last').text(id); }); $('.click').click(function() { var $ele = $(this).next('div').find('[id^="clickCount"]'); clickCallbacks.fireWith($ele, [this.id]); //do two separate but related things. }); 
  3. 你现在可以拥有多个callback批次的函数,你可以在你认为有必要的时候调用它,而不需要在你的代码中做太多的修改。

当使用相同的方法更新不同的DOM元素时,我可以看到callback很有用。

这是一个俗气的例子: http : //jsfiddle.net/UX5Ln/

 var clickCallbacks = $.Callbacks(); clickCallbacks.add(function() { var c = parseInt(this.text(), 10); this.text(c + 1); }); clickCallbacks.add(function(id) { $('span', '#last').text(id); }); $('.click').click(function() { var $ele = $(this).next('div').find('[id^="clickCount"]'); clickCallbacks.fireWith($ele, [this.id]); }); 

它会更新点击计数器和点击“最后点击”。

一个(几乎)开箱即用的jQuery Pub / Sub系统

这是恕我直言的最有趣的应用程序,因为它没有清楚地在答案中说明(虽然有些人暗示使用),我将它添加到这个相对较旧的职位。

注意:这个用法很明显,在jQuery文档中有一个例子,但是我猜这是在问题发布之后添加的。

Pub / sub ,也就是观察者模式 ,是一种在应用程序中促进松耦合单一责任的模式。 对象不是直接调用其他对象的方法,而是使用对象来订阅特定的任务或活动,并在发生时通知它们。 有关使用发布/订阅模式的好处的更详细的解释,您可以检查为什么会使用发布/订阅模式(在JS / jQuery中)? 。

当然, 这可以通过使用trigger.on().on() 自定义事件来实现,但是我发现jQuery.Callbacks更适合于任务,生成更jQuery.Callbacks代码。

以下是jQuery文档中的示例代码片段:

 var topics = {}; jQuery.Topic = function( id ) { var callbacks, method, topic = id && topics[ id ]; if ( !topic ) { callbacks = jQuery.Callbacks(); topic = { publish: callbacks.fire, subscribe: callbacks.add, unsubscribe: callbacks.remove }; if ( id ) { topics[ id ] = topic; } } return topic; }; 

和一个用法示例:

 // Subscribers $.Topic( "mailArrived" ).subscribe( fn1 ); $.Topic( "mailArrived" ).subscribe( fn2 ); $.Topic( "mailSent" ).subscribe( fn1 ); // Publisher $.Topic( "mailArrived" ).publish( "hello world!" ); $.Topic( "mailSent" ).publish( "woo! mail!" ); // Here, "hello world!" gets pushed to fn1 and fn2 // when the "mailArrived" notification is published // with "woo! mail!" also being pushed to fn1 when // the "mailSent" notification is published. /* output: hello world! fn2 says: hello world! woo! mail! */ 

看起来, $.Callbacks是作为一个实现细节开始的:一种pipe理函数列表的方法,以相同的参数调用给定列表中的所有函数。 有点像C#的多播委托 ,还有一些额外的function,比如你可以传递的标志来定制列表的行为。

一个很好的例子可能是jQuery在内部使用$.Callbacks来实现它的ready事件。 bindReady()初始化一个callback列表:

 readyList = jQuery.Callbacks( "once memory" ); 

注意oncememory标志,确保callback列表只会被调用一次,并且列表被调用后添加的函数将被立即调用。

然后, ready()将指定的处理程序添加到该列表中:

 ready: function( fn ) { // Attach the listeners jQuery.bindReady(); // Add the callback readyList.add( fn ); return this; } 

最后,当DOM准备就绪时,callback列表被触发:

 readyList.fireWith( document, [ jQuery ] ); 

所有ready处理程序都是在同一个文档的上下文中调用的,对全局jQuery对象的引用相同。 它们只能被调用一次,而传递给ready()其他处理程序将立即被调用,所有这些$.Callbacks

我没有看到有关设置上下文的具体提及,但是由于您可以传递任意数量的参数,因此可能会有用。 你也可以使自己的约定传递一个标志作为第一个参数,并且如果监听器不是为了处理剩下的参数列表而立即返回false。

我遇到过类似这样的情况可能会有用的情况,但是用bind()和trigger()来代替自定义事件。 想象一下一些消息处理系统(一个基于networking的聊天室或电子邮件客户端),你在这里轮询新消息的服务。 一个function可能是在一个范围内设置一个数字,或者在发生事件时显示一个咆哮。 另一个可能是更新网格。 使用触发器,您将不得不为每个侦听器触发事件​​,并从eventData中“展开”传递的参数,使用callback函数,它只是一个触发器,您的侦听器是一个带简单参数列表的简单JavaScript函数。

callback不完全是革命性的,但它会使代码更less,更干净。

我正在开发一个有很多业务逻辑和至less11个外部服务的应用程序。 如果您可以使用类似callback的方式编写自己的stream控制类和行为,而不是试图强制延迟实现的意愿,那么它确实有助于保持直线。