`
zhouyrt
  • 浏览: 1174377 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

读jQuery之十九(多用途回调函数列表对象)

 
阅读更多

$.Callbacks是在版本1.7中新加入的。它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。

整个$.Callbacks的源码不到200行,它是一个工厂函数,使用函数调用方式(非new,它不是一个类)创建对象,它有一个可选参数flags用来设置回调函数的行为。

$.Callbacks是在jQuery内部使用,如为$.ajax,$.Deferred等组件提供基础功能的函数。它也可以用在类似功能的一些组件中,如自己开发的插件。

 

$.Callbacks构造的对象(以callbacks示例)主要包括以下方法:

  1. callbacks.add
  2. callbacks.remove
  3. callbacks.has
  4. callbacks.empty
  5. callbacks.disable
  6. callbacks.fire
  7. callbacks.fireWith
  8. callbacks.fired
  9. callbacks.lock
  10. callbacks.locked

1. callbacks.add 添加一个函数到回调队列

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
 
var callbacks = $.Callbacks();
// 方式1
callbacks.add(fn1);
// 方式2 一次添加多个回调函数
callbacks.add(fn1, fn2);
// 方式3 传数组
callbacks.add([fn1, fn2]);
// 方式4 函数和数组掺和
callbacks.add(fn1, [fn2]);

传数组进去实际在add内部判断如果是数组会递归调用私有的add函数。此外,需注意add方法默认不去重,比如这里fn1添加两次,fire时会触发两次。私有add方法有趣,它使用了具名函数立即执行其名仅在函数内可用。如图中所圈之处

 

2. callbacks.remove 从回调队列中删除一个函数

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
var callbacks = $.Callbacks();
callbacks.add(fn1, fn2);
callbacks.remove(fn1);

 此时fire只会触发fn2了。

 

此外remove方法会把添加多次的函数如fn1,全部删除掉。为此还和cmcnick讨论为啥remove内部不用if而用while(开始我以为是jQuery写错了)。如下

var callbacks = $.Callbacks();
callbacks.add(fn1, fn2, fn1, fn2);
callbacks.remove(fn1);

 

此时会把add两次的fn1都删掉,fire时只触发fn2两次。换成if则只删fn1一次。

 

3. callbacks.has 判断是否添加过某回调函数,不想重复添加时很有用

function fn1() {
    console.log(1)
}
var callbacks = $.Callbacks();
callbacks.add(fn1);
if (!callbacks.has(fn1)) {
    callbacks.add(fn1);
}

 

4. callbacks.empty 清空所有的回调函数

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
var callbacks = $.Callbacks();
callbacks.add(fn1);
callbacks.add(fn2);
callbacks.empty();

 此时再fire不会触发任何函数。empty函数实现很简单,只是把内部的队列管理对象list重置为一个空数组。这里可以了解清空数组的几种方式

 

5. callbacks.disable 禁用该对象

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
var callbacks = $.Callbacks();
callbacks.disable();
callbacks.add(fn1); // 不起作用
callbacks.add(fn2); // 不起作用
callback.remove(fn1); // 不起作用
callbacks.fire(); // 不起作用

 调用后再使用add, remove, fire等方法均不起作用。该方法内不是实际是将队列管理对象list、stack、memory都置undefined了。

 

6. callbacks.fire 主动触发添加回调函数

function fn() {
    console.log(this); // 上下文是callbacks
    console.log(arguments); // [3]
}
var callbacks = $.Callbacks();
callbacks.add(fn);
callback.fire(3);

 前面已经提到了,fire方法用来触发回调函数,默认的上下文是callbacks对象,还可以传参给回调函数。

 

7. callbacks.fireWith 同fire,但可以指定执行上下文

function fn() {
    console.log(this); // 上下文是person
    console.log(arguments); // [3]
}
var person = {name: 'jack'};
var callbacks = $.Callbacks();
callbacks.add(fn);
callback.fireWith(person, 3);

 其实fire内部调用的是fireWith,只是将上下文指定为this了,而this正是$.Callbacks构造的对象。

 

8. callbacks.fired 判断是否有主动触发过(调用fire或fireWith方法)

function fn1() {
    console.log(1)
}
var callbacks = $.Callbacks();
callbacks.add(fn1);
callbacks.fired(); // false
callbacks.fire();
callbacks.fired(); // true

 

注意,只要调用过一次fire或fireWith就会返回true。

 

9. callbacks.lock 锁定队列的状态

 

10. callbacks.locked 判断是否锁定状态

 

 

$.Callbacks构造时可配置的参数Flags是可选的,字符串类型以空格分隔,有如下

  1. once
  2. memory
  3. unique
  4. stopOnFalse

1. once 确保回调函数仅执行一次

function fn() {
    console.log(1)
}
var callbacks = $.Callbacks('once');
callbacks.add(fn);
callbacks.fire(); // 打印1
callbacks.fire(); // fn不再触发

 

2. memory 记忆callbacks

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
var callbacks = $.Callbacks('memory');
callbacks.add(fn1);
callbacks.fire(); // 必须先fire
callbacks.add(fn2); // 此时会立即触发fn2

 

memory有点绕,本意是记忆的意思。实际它的用法有点诡异,需结合特定场景来看(如jQuery.Deferred)。当首次调用fire后, 之后每次add都会立即触发。比如先callbacks.fire(),再callbacks.add(fn1),这时fn1会立即被调用。

 

如果是批量添加的,也都会被触发

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
function fn3() {
    console.log(3)
}
var callbacks = $.Callbacks('memory');
callbacks.add(fn1);
callbacks.fire();
callbacks.add([fn2, fn3]); // output 2, 3

 

3. unique 去除重复的回调函数

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
}
var callbacks = $.Callbacks('unique');
callbacks.add(fn1);
callbacks.add([fn1, fn2]); // 再次添加fn1
callbacks.fire(); // output 1, 2

 

这个很好理解,之前用has判断去重,使用unique属性则更方便。本例先add一次fn1,第二次再add时内部则会去重。因此最后fire时只输出“1,2”而不是“1,1,2”。

 

4. stopOnFalse 回调函数返回false时中断回调队列的迭代

function fn1() {
    console.log(1)
}
function fn2() {
    console.log(2)
    return false // 注意这里
}
function fn3() {
    console.log(3)
}
var callbacks = $.Callbacks('stopOnFalse');
callbacks.add(fn1, fn2, fn3);
callbacks.fire(); // output 1,2

 

从该属性名就能知了它的意图,即回调函数通过return false来停止后续的回调执行。该示例添加了3个回调,fn2中使用return false,当fire执行到fn2时会停止执行,后续的fn3就不会被调用了。

 

用$.Callbacks实现观察者模式

// 观察者模式
var observer = {
    hash: {},
    subscribe: function(id, callback) {
        if (typeof id !== 'string') {
            return
        }
        if (!this.hash[id]) {
            this.hash[id] = $.Callbacks()
            this.hash[id].add(callback)
        } else {
            this.hash[id].add(callback)
        }
    },
    publish: function(id) {
        if (!this.hash[id]) {
            return
        }
        this.hash[id].fire(id)
    }
}
 
// 订阅
observer.subscribe('mailArrived', function() {
    alert('来信了')
})
observer.subscribe('mailArrived', function() {
    alert('又来信了')
})
observer.subscribe('mailSend', function() {
    alert('发信成功')
})
 
// 发布
setTimeout(function() {
    observer.publish('mailArrived')
}, 5000)
setTimeout(function() {
    observer.publish('mailSend')
}, 10000)

 

注:阅读版本为1.8.3

 

 

 

 

 

 


 

 

 

  • 大小: 14.1 KB
分享到:
评论
1 楼 yanhaijing 2013-08-08  
有点意思

相关推荐

    jQuery.Callbacks()回调函数队列用法详解

    jQuery Callbacks是jQuery库中的一个功能强大的工具,用于管理和执行回调函数列表。通过创建callback对象,开发者可以添加、移除、触发和禁用回调函数,使得回调管理更为灵活和方便。自jQuery 1.7版本开始引入,...

    JQuery1.10.2(含vsdoc智能提示)

    它接受两个参数:一个数组(或可迭代对象)和一个回调函数。回调函数对每个元素执行操作,并返回一个新的数组,新数组的元素是回调函数的返回值。 - 示例: ```javascript var arr = [1, 2, 3]; var mappedArr =...

    jquery1.7 中文API.rar

    2. **$.when()** 改进:这个函数现在可以接受多个Promise对象作为参数,当所有Promise都完成时,会触发指定的回调函数。 3. **$.each()** 优化:在处理大型数组时,$.each()的性能有所提升,这对于处理大量数据的...

    jquery1.7中文文档

    1. **Deferred对象(Deferred Objects)**: 1.7版本引入了Deferred对象,用于更好地管理异步操作,如Ajax请求和动画,支持链式调用和回调函数。 2. **事件绑定优化(Event Bindings)**: jQuery 1.7改进了事件绑定...

    jQuery 遍历函数详解

    .each()函数是一个非常通用的迭代函数,能够为集合中的每一个元素执行一个回调函数。对于数组和对象都有很好的适用性。 .end()函数用来结束当前链式操作中的最近一次筛选操作,返回到前一次的状态。这通常用在多重...

    jQuery1.7和1.11.3的汉化API

    在动画效果上,jQuery1.7继续完善了$.animate()函数,增加了更多的可定制选项,如easing(缓动函数)和step(每帧回调函数),让开发者可以实现更多复杂的动画效果。同时,$.fx.speeds对象允许开发者自定义动画速度...

    Jquery操作Ajax方法小结

    它接受一个URL参数,以及可选的发送到服务器的数据和一个回调函数。在回调函数中可以处理从服务器返回的数据。此方法的一个常见用途是获取服务器上的资源或数据,并在页面上进行异步更新。 $.getScript()方法用于从...

    JQUERY3.3.1

    开发者可以自定义速度和回调函数,实现复杂的动态效果。 **Ajax交互**:jQuery的`.ajax()`方法使得异步数据交换变得简单。它支持GET和POST请求,以及JSON、XML等多种数据格式。还有`.load()`, `.get()`, `.post()`...

    jquery form ui中文api

    - **参数**:可以接受一个回调函数或者一个配置选项对象。 - **链式调用**:支持链式调用。 - **示例**: ```javascript $('#myFormId').ajaxForm(); ``` 2. **ajaxSubmit** - **用途**:立即通过Ajax方式...

    日历控件(Jquery)

    - `onSelect`:当用户选择日期时触发的回调函数。 6. **优化与性能**: - 使用CDN加速文件加载。 - 按需引入,避免加载不必要的功能和样式。 - 对于移动设备,考虑使用响应式设计或专门的移动版本日历插件。 7...

    jQuery 1.8 API中文版文档

    例如,`$(selector).hide(speed, easing, callback)` 方法,用于隐藏选定元素,速度参数可以是"slow", "fast"或毫秒值,easing是动画平滑效果,callback是动画结束后执行的回调函数。 **使用技巧** 1. **链式操作*...

    jQuery1.11.0.chm

    例如,`.get('url', data, success)`用于发送GET请求,`success`参数是请求成功后的回调函数。`.getJSON()`则专门用于获取JSON数据。 六、链式操作(Chaining) jQuery的一个重要特性是链式操作,允许连续调用多个...

    jquery完全笔记 带目录 高清 经典前端js笔记 前端必看

    在jQuery中,回调函数通常与动画和事件处理程序一起使用。 #### 10. jQuery链式调用 jQuery的链式调用允许开发者在一个语句中完成多个操作,从而提高代码的可读性和效率。 #### 11. jQuery捕获与过滤 捕获允许...

    jquery.exif_javascript_exif_jquery_

    2. **文件读取**:使用`FileReader`对象的`readAsDataURL`方法,可以将选中的图片文件转换为Base64编码的字符串,这一步是异步的,通常会提供一个回调函数来处理数据。 3. **解析Exif数据**:当`FileReader`的`...

    jquery Date Range Picker

    3. **事件处理**:提供了多种事件回调函数,如`onSelect`、`onClose`等,允许开发者在用户选择日期时执行特定的代码逻辑。 4. **格式化日期输出**:可以设置日期的显示格式,例如“YYYY-MM-DD”、“MM/DD/YYYY”等。...

    jQuery基础教程(第2版).pdf 下载.rar 下载

    2. **链式操作**:jQuery方法返回的是jQuery对象,这使得多个操作可以连续进行,如`$("#element").hide().addClass("hidden")`,先隐藏元素,再添加一个"hidden"类。 3. **事件处理**:jQuery简化了事件绑定,如`$...

    jQuery 祝福墙

    // 拖动停止时的回调函数 } }); ``` 在祝福墙上,用户可能需要拖动祝福卡片到合适的位置,这就是拖拽功能的用途。 ### 6. 数据存储与加载 为了保存用户的祝福信息,开发者可能使用了本地存储(localStorage 或 ...

    jqueryapi能帮你学会如何用jquery

    通过调整参数,可以精确控制动画的速度、延迟和回调函数。 Ajax交互是jQuery另一个强项,`$.ajax()`, `$.get()`, `$.post()`等函数使得异步数据请求变得轻而易举,同时jQuery处理了跨域、JSONP等问题,使得与服务器...

Global site tag (gtag.js) - Google Analytics