欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

jQuery Callback的基本实现和使用方法

程序员文章站 2022-05-14 14:02:50
...
在 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的基本实现和使用方法的详细内容,更多请关注其它相关文章!