jQuery.Callbacks()
一个多用途的回调列表对象,提供了强大的的方式来管理回调函数列表。
jQuery.Callbacks(flags)
- flags类型: String。一个用空格标记分隔的标志可选列表,用来改变回调列表中的行为。
$.Callbacks()
的内部提供了jQuery的$.ajax()
和$.Deferred()
基本功能组件。它可以用来作为类似基础定义的新组件的功能。
$.Callbacks()
支持的方法,包括callbacks.add()
,callbacks.remove()
,callbacks.fire()
和callbacks.disable()
.
入门
以下是两个方法命名fn1
和fn2
:
function fn1( value ) { console.log( value ); }function fn2( value ) { fn1("fn2 says: " + value);return false; }
这些可以添加为回调函数作为一个$.Callbacks
的列表,并调用如下:
var callbacks = $.Callbacks(); callbacks.add( fn1 ); // outputs: foo! callbacks.fire( "foo!" ); callbacks.add( fn2 ); // outputs: bar!, fn2 says: bar! callbacks.fire( "bar!" );
这样做的结果是,它使构造复杂的回调列表变得简单,输入值可以通过尽可能多的函数根据需要轻松使用。
用于以上的两个具体的方法:.add()
方法支持将新的回调添加到回调列表,而.fire()
方法执行添加的功能,并提供一种传递参数的方法,该参数将由同一列表中的回调处理。
另一种方法由$.Callbacks
的.remove()
,它具有从回调列表中删除特定回调的功能。
下面是.remove()使用的一个例子:
var callbacks = $.Callbacks(); callbacks.add( fn1 ); // outputs: foo! callbacks.fire( "foo!" ); callbacks.add( fn2 ); // outputs: bar!, fn2 says: bar! callbacks.fire( "bar!" ); callbacks.remove( fn2 ); // only outputs foobar, as fn2 has been removed. callbacks.fire( "foobar" );
支持Flags
这个flags
参数是$.Callbacks()
的一个可选参数,结构为由空格分隔的字符串列表,这些字符串更改了回调列表的行为(比如.$.Callbacks('unique stopOnFalse')
).
可用的 flags:
once
:确保回调列表只能被触发一次(如延迟)memory
:跟踪先前的值,并在使用最新的“已存储”值(如Deferred)立即触发列表后调用添加的任何回调。unique
:确保回调只能添加一次(因此列表中没有重复项)。stopOnFalse
:当回调返回false
时中断呼叫。
默认情况下,回调列表的作用类似于事件回调列表,并且可以“触发”多次。
有关flags
理想使用方法的示例,请参见下文
$.Callbacks("once")
var callbacks = $.Callbacks( "once" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); /* output: foo */
$.Callbacks("memory")
var callbacks = $.Callbacks( "memory" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); /* output: foo fn2 says:foo bar fn2 says:bar foobar */
$.Callbacks("unique")
var callbacks = $.Callbacks( "unique" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn1 ); // repeat addition callbacks.add( fn2 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); /* output: foo bar fn2 says:bar foobar */
$.Callbacks("stopOnFalse")
function fn1( value ){ console.log( value );return false; }function fn2( value ){ fn1( "fn2 says: " + value );return false; }var callbacks = $.Callbacks( "stopOnFalse" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn2 ); callbacks.fire( "bar" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); /* output: foo bar foobar */
因为$.Callbacks()
支持一个列表的flags(标识)而不仅仅是一个,设置几个flags(标识),有一个累积效应,类似“&&”。这意味着可以组合标志来创建回调列表,这两个列表都是唯一的,并确保列表是否已被触发,添加更多回调将使用最新的触发值(即$.Callbacks("unique memory")
)调用它。
$.Callbacks('unique memory')
function fn1( value ) { console.log( value );return false; }function fn2( value ) { fn1( "fn2 says: " + value );return false; }var callbacks = $.Callbacks( "unique memory" ); callbacks.add( fn1 ); callbacks.fire( "foo" ); callbacks.add( fn1 ); // repeat addition callbacks.add( fn2 ); callbacks.fire( "bar" ); callbacks.add( fn2 ); callbacks.fire( "baz" ); callbacks.remove( fn2 ); callbacks.fire( "foobar" ); /* output: foo fn2 says:foo bar fn2 says:bar baz fn2 says:baz foobar */
Flag结合体是使用的$.Callbacks()
内部的.done()
和.fail()
一个递延容器-它们都使用$.Callbacks('memory once')
.
$.Callbacks
方法也可以被分离,为方便起见应该有一个需要定义简写版本:
var callbacks = $.Callbacks(), add = callbacks.add, remove = callbacks.remove, fire = callbacks.fire; add( fn1 ); fire( "hello world" ); remove( fn1 );
$.Callbacks,$.Deferred and Pub/Sub
pub/sub
(发布/订阅,或观察者模式)背后的总体思想是促进应用程序之间的松耦合。一个对象而不是单个对象调用其他对象的方法,而是订阅另一个对象的特定任务或活动,并在该对象发生时得到通知。观察者也称为订阅者,我们将被观察的对象称为发布者(或主题)。事件发生时,发布者会通知订阅者。
为了演示的组件创建功能$.Callbacks()
,有可能仅使用回调列表来实现pub/sub
系统。使用$.Callbacks()
为主题的队列,用于发布和订阅主题可以实现如下的系统:
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! */
尽管这很有用,但可以进一步实施。使用$.Deferreds
,可以确保发布者仅在完成(解决)特定任务后才发布订阅者的通知。请参阅下面的代码示例,以获取有关如何在实践中使用它
// subscribe to the mailArrived notification $.Topic( "mailArrived" ).subscribe( fn1 ); // create a new instance of Deferredsvar dfd = $.Deferred(); // define a new topic (without directly publishing)var topic = $.Topic( "mailArrived" ); // when the deferred has been resolved, publish a // notification to subscribers dfd.done( topic.publish ); // Here the Deferred is being resolved with a message // that will be passed back to subscribers. It's possible to // easily integrate this into a more complex routine // (eg. waiting on an ajax call to complete) so that // messages are only published once the task has actually // finished. dfd.resolve( "it's been published!" );