什么是回调函数?
在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。
这一设计允许了底层代码调用在高层定义的子程序。
引用自维基百科
编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写库;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。
所以在抽象层的图示里,库位于应用的底下。
当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。
作者:桥头堡
链接:https://www.zhihu.com/question/19801131/answer/27459821
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
举个栗子
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
作者:常溪玲
链接:https://www.zhihu.com/question/19801131/answer/13005983
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
jQuery中
jQuery Callback 函数
Callback 函数在当前动画 100% 完成之后执行。
例如
$(selector).hide(speed,callback)
举个栗子
示例代码部分来自 jQuery API
$("button").click(function(){
$("p").hide(1000);
});
错误(没有 callback)
$("p").hide(1000);
alert("The paragraph is now hidden");
//没hide完就弹出了alert
正确(有 callback)
$("p").hide(1000,function(){
alert("The paragraph is now hidden");
});
Callbacks是jQuery 1.7引入的方法
一个多用途的回调列表对象,主要用于管理一组有相同方法参数的回调函数
.Callbacks()的内部提供了jQuery的 .ajax() 和 $.Deferred() 基本功能组件。它可以用来作为类似基础定义的新组件的功能。
jQueryjQuery.callbacks(flags)
function fn1( value ){
console.log( value );
}
function fn2( value ){
fn1("fn2 says:" + value);
return false;
}
var callbacks = $.Callbacks();
callbacks.add( fn1 );
callbacks.fire( "foo!" ); // outputs: foo!
callbacks.add( fn2 );
callbacks.fire( "bar!" ); // outputs: bar!, fn2 says: bar!
这样做的结果是,它使构造复杂的回调列表变得简单,输入值可以通过尽可能多的函数根据需要轻松使用。
- callbacks.add(callbacks)//添加一个回调或回调的集合
- callbacks.remove(callbacks)//删除回调或回调回调列表的集合
callbacks: 一个函数,或者一个函数数组用来添加到回调列表。
- callbacks.fire(arguments) //用给定的参数调用所有的回调
arguments: 这个参数或参数列表传回给回调列表
var callbacks = $.Callbacks();
callbacks.add( fn1 );
callbacks.fire( "foo!" ); // outputs: foo!
callbacks.add( fn2 );
callbacks.fire( "bar!" ); // outputs: bar!, fn2 says: bar!
callbacks.remove(fn2);
callbacks.fire( "foobar" );
// only outputs foobar, as fn2 has been removed.
Flags
一个可选参数, 结构为一个用空格标记分隔的标志可选列表,用来改变回调列表中的行为
可用的 flags:
once: 确保这个回调列表只执行一次(像一个递延 Deferred).
memory: 保持以前的值和将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).
unique: 确保一次只能添加一个回调(所以有没有在列表中的重复).
stopOnFalse: 当一个回调返回false 时中断调用
//$.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( '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.disable()
无参数,禁用回调列表中的回调
callbacks.empty()
无参数,从列表中删除所有的回调
callbacks.fired()
本身返回bool值 如果列表中的回调至少有一次被呼叫返回true 否则返回false
callbacks.fireWith([context][,args])
context: 该列表中的回调被触发的上下文引用
args: 一个参数或参数列表传回给回调列表。
fire调用的时候,我们添加函数当中的this指向我们的Callbacks实例,例如
var cb = $.Callbacks();
cb.add(function () {
console.log(this === cb);
});
cb.fire();//true
fireWith就是改变我们添加函数的context,即this指向,例如
var cb = $.Callbacks();
var obj = {
name: 'objName'
};
cb.add(function (age) {
console.log(this.name, age);
});
cb.fireWith(obj, [26]);//objName 26
fireWith第一个参数是我们的context,第二个参数是我们需要传递的内容数组,注意了是数组!
callbacks.has(callbacks)
callbacks:用来搜索的回调
// a sample logging function to be added to a callbacks list
var foo = function( value1, value2 ){
console.log( 'Received:' + value1 + ',' + value2 );
}
// a second function which will not be added to the list
var bar = function( value1, value2 ){
console.log( 'foobar');
}
var callbacks = $.Callbacks();
// add the log method to the callbacks list
callbacks.add( foo );
// determine which callbacks are in the list
console.log( callbacks.has( foo ) ); // true
console.log( callbacks.has( bar ) ); // false
callbacks.lock()
锁定在其当前状态的回调列表
// a sample logging function to be added to a callbacks list
var foo = function( value ){
console.log( 'foo:' + value);
}
var callbacks = $.Callbacks();
// add the logging function to the callback list
callbacks.add( foo );
// fire the items on the list, passing an argument
callbacks.fire( 'hello' );
// outputs 'foo: hello'
// lock the callbacks list
callbacks.lock();
// try firing the items again
callbacks.fire( 'world' );
// as the list was locked, no items
// were called so 'world' isn't logged
callbacks.locked()
确定是否已被锁定的回调列表,同fired()
$.Callbacks
, $.Deferred
and Pub/Sub
pub / sub( Observer模式)背后的一般思路 是促进应用程序的松散耦合。而比对其他对象的方法调用的单个对象,一个对象,而不是另一个对象的一个特定的任务或活动,并通知当它发生。观察家也被称为订阅者,我们指的出版商(或主体)观察对象。出版商事件发生时通知用户
作为一个组件 .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 Deferreds
var 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( "its been published!" );