在 js 开发中,由于没有多线程,经常会遇到回调这个概念,比如说,在 ready 函数中注册回调函数,注册元素的事件处理等等。在比较复杂的场景下,当一个事件发生的时候,可能需要同时执行多个回调方法,可以直接考虑到的实现就是实现一个队列,将所有事件触发时需要回调的函数都加入到这个队列中保存起来,当事件触发的时候,从这个队列重依次取出保存的函数并执行。
概述
$(document).ready()的简写。
允许你绑定一个在dom文档载入完成后执行的函数。这个函数的作用如同$(document).ready()一样,只不过用这个函数时,需要把页面中所有需要在 dom 加载完成时执行的$()操作符都包装到其中来。从技术上来说,这个函数是可链接的--但真正以这种方式链接的情况并不多。 你可以在一个页面中使用任意多个$(document).ready事件。参考 ready(function) 获取更多 ready 事件的信息。
参数
callbackfunctionv1.0
当dom加载完成后要执行的函数
可以如下简单的实现。
首先,实现一个类函数来表示这个回调类。在 javascript 中,使用数组来表示这个队列。
function callbacks() { this.list = [];
}
然后,通过原型实现类中的方法。增加和删除的函数都保存在数组中,fire 的时候,可以提供参数,这个参数将会被传递给每个回调函数。
callbacks.prototype = {
add: function(fn) {
this.list.push(fn);
},
remove: function(fn){
var position = this.list.indexof(fn);
if( position >=0){
this.list.splice(position, 1);
}
},
fire: function(args){
for(var i=0; i<this.list.length; i++){
var fn = this.list[i];
fn(args);
}
}
};
测试代码如下:
function fn1(args){
console.log("fn1: " + args);
}
function fn2(args){
console.log("fn2: " + args);
}
var callbacks = new callbacks();
callbacks.add(fn1);
callbacks.fire("alice");
callbacks.add(fn2);
callbacks.fire("tom");
callbacks.remove(fn1);
callbacks.fire("grace");
或者,不使用原型,直接通过闭包来实现。
function callbacks() {
var list = [];
return {
add: function(fn) {
list.push(fn);
},
remove: function(fn){
var position = list.indexof(fn);
if( position >=0){
list.splice(position, 1);
}
},
fire: function(args) {
for(var i=0; i<list.length; i++){
var fn = list[i];
fn(args);
}
}
};
}
这样的话,示例代码也需要调整一下。我们直接对用 callbacks 函数就可以了。
function fn1(args){
console.log("fn1: " + args);
}
function fn2(args){
console.log("fn2: " + args);
}
var callbacks = callbacks();
callbacks.add(fn1);
callbacks.fire("alice");
callbacks.add(fn2);
callbacks.fire("tom");
callbacks.remove(fn1);
callbacks.fire("grace");
下面我们使用第二种方式继续进行。
对于更加复杂的场景来说,我们需要只能 fire 一次,以后即使调用了 fire ,也不再生效了。
比如说,可能在创建对象的时候,成为这样的形式。这里使用 once 表示仅仅能够 fire 一次。
var callbacks = callbacks("once");
那么,我们的代码也需要进行一下调整。其实很简单,如果设置了 once,那么,在 fire 之后,将原来的队列中直接干掉就可以了。
function callbacks(options) {
var once = options === "once";
var list = [];
return {
add: function(fn) {
if(list){
list.push(fn);
}
},
remove: function(fn){
if(list){
var position = list.indexof(fn);
if( position >=0){
list.splice(position, 1);
}
}
},
fire: function(args) {
if(list)
{
for(var i=0; i<list.length; i++){
var fn = list[i];
fn(args);
}
}
if( once ){
list = undefined;
}
}
};
}
jquery 中,不只提供了 once 一种方式,而是提供了四种类型的不同方式:
once: 只能够触发一次。
memory: 当队列已经触发之后,再添加进来的函数就会直接被调用,不需要再触发一次。
unique: 保证函数的唯一
stoponfalse: 只要有一个回调返回 false,就中断后继的调用。
这四种方式可以组合,使用空格分隔传入构造函数即可,比如 $.callbacks(once memory unique);
官方文档中,提供了一些使用的示例。
callbacks.add(fn1, [fn2, fn3,...])//添加一个/多个回调
callbacks.remove(fn1, [fn2, fn3,...])//移除一个/多个回调
callbacks.fire(args)//触发回调,将args传递给fn1/fn2/fn3……
callbacks.firewith(context, args)//指定上下文context然后触发回调
callbacks.lock()//锁住队列当前的触发状态
callbacks.disable()//禁掉管理器,也就是所有的fire都不生效
以上就是jquery callback的基本实现和使用方法的详细内容。