jquery.Callbacks的实现

前言

本人是一个热爱前端的菜鸟,一直喜欢学习js原生,对于jq这种js库,比较喜欢理解他的实现,虽然自己能力有限,水平很低,但是勉勉强强也算是能够懂一点吧,对于jq源码解读系列,博客园里有很多,推荐大神  艾伦的jq系列,在这里,我仅仅是分享一下我对jq里的Callbacks模块的理解与详细介绍一下我自己仿jq实现的一个callback功能。

功能介绍

jq的Callbacks模块主要是为其他模块提供服务的,他就像一个温柔的小女人,在背后默默地付出。Deferred就像一个巨人,在jq中那么的突出,但在内部,他受到Callbacks的服务。

Callbacks的几种状态:

  • once    -- 回调函数只执行一次
  • unique    -- 函数不能重复添加到回调列表中
  • memory    -- 状态记忆,主要用于Deferred中
  • stopOnFalse    -- 遇到return false 终止回调列表继续执行

我自己实现的Callbacks的几个简单的方法

  • add    -- 向对应的回调函数列表添加一个函数
  • fire    -- 触发回调,回调函数列表依次执行函数
  • has    -- 回调函数列表是否存在传入函数
  • clear    -- 清空回调函数列表

整体结构

首先,我们要向得到一个想要的Callbacks模块,需要这样做:

var cb = Callback(‘memory once‘)    // 得到一个拥有记忆功能并只执行一次的回调模块

由于我们需要基于一定状态来得到不同的实例,我们可以确定,我们需要一个存储状态的对象

var callbackState = {}

我们给Callback函数传入了‘memory once‘,我们怎么记录这两个状态呢,在这里,仿jq来写的一个函数来实现,如下:

var createCallbackState = function (options) {
    var states = options.split(‘ ‘)
    var obj = {}
    for (var i = 0; i < states.length; i++) {
      obj[states[i]] = true
    }
    return obj
  }

以上代码,将‘memory once‘ 变成了 {memory: true, once: true},如果状态缓存对象里有这个对象,直接返回,没有的话先创建再返回。

接下来,就是Callback函数的全部代码了,先上代码

var Callback = function (options) {

    var state = callbackState[options]  //获取状态模式
    if (!state) {
      callbackState[options] = state = createCallbackState(options)
    }
    var list = [],  // 回调函数列表
      memory,       // 存储是否为 记忆状态
      has = function (fn) {
        for (var i = 0; i < list.length; i++) {
          if (list[i] === fn) {
            return true
          }
        }
        return false
      },
      add = function () {
        var i = 0,
          args = arguments,
          len = args.length
        for (; i < len; i++) {
          if (state.unique && has(args[i])) { // 如果是unique状态下并回调列表已经拥有该函数,则不添加
            continue
          }
          list.push(args[i])
        }
      },
      fire = function (context, args) {
        var i = 0,
          len = list.length,
          item
        for (; i < len; i++) {
          item = list[i]
          if (item.apply(context,args) === false && state.stopOnFalse) {  //如果函数运行返回false,并且是stopOnFalse状态,终止循环
            break;
          }
        }
      }

    return {
      add: function () {
        add.apply(null,arguments)
        // 如果memory模式并且已经拥有了memory信息,接着出发函数
        if (state.memory && memory) {
          fire(memory[0], memory[1])
          list = []
        }
      },
      fire: function (context, args) {
        // 如果memory模式,并且list是空,代表触发在添加前,保存memory信息
        if (state.memory && !list.length) {
          memory = [context, args]
          return
        }
        fire(context,args)
        if (state.once) {
          this.clear()
        }
      },
      has: function (fn) {
        return has(fn)
      },
      clear: function () {
        list = []
      }
    }

  }

Callback函数执行后,返回一个对象,然后该对象包含了几个简单的功能。下面我来介绍一下这部分的实现。

首先,如jq一样,我也定义了内部的add, fire, has方法,主要原因是逻辑需要,在返回对象的方法中实现once,memory状态控制,内部的add,fire方法是纯粹的添加和触发函数。

先来看cb.add方法,add方法可以接收多个函数,因此

add.apply(null,arguments)

使用内部的add做添加功能

再往下的一部分的功能是判断这个回调模块是否是memory状态,理解Deferred模块的同学应该知道,该模块是Promise模式,订阅成功或失败状态的回调函数,然后再某一时刻触发他,这个模式便引用了memory状态下的Callback,这个模式有一个奇怪的地方,如果你先发布成功,但是回调列表空空如也,那么程序并不会发布失败,而是等待成功回调函数的加入,一但回调函数加入,立刻执行他。就是如下代码

// 如果memory模式并且已经拥有了memory信息,立刻触发函数
 if (state.memory && memory) {
   fire(memory[0], memory[1])
   list = []
 }

提示 : ‘如果你先发布成功,但是回调列表空空如也,那么程序并不会发布失败,而是等待成功回调函数的加入,一但回调函数加入,立刻执行他’ 的理解如下代码

var cb = Callback(‘memory‘) // 得到记忆功能的回调模块

cb.fire() // 触发回调队列

cb.add(fn) //添加回调函数,自动执行了!

function fn () {
  console.log(‘fn‘)
}

如果在非memory状态,以上代码无效。需要再次fire才会执行。

经过上述,fire函数也好理解了,fire可接收两个参数,函数上下文,函数参数数组。

与add中memory状态的代码连串起来,以下代码就是fire时memory状态下的操作

// 如果memory模式,并且list是空,代表触发在添加前,保存memory信息
        if (state.memory && !list.length) {
          memory = [context, args]
          return
        }

如果是memory状态,回调列表为空,就保存函数执行上下文和参数数组,等add时立刻执行。

除了上述以外,代码就很简单易懂啦,Callback函数就到这里了,很简单的功能,唯一一点不好理解的就是memory状态。再次声明:本人菜鸟一枚, 如有错误,请指正,轻喷轻喷~~~~

如深入学习源码,请转至 艾伦 jq源码解读系列。高手带你读源码。。。。。

时间: 2024-10-01 06:24:21

jquery.Callbacks的实现的相关文章

jQuery.callbacks 注释

1 (function( jQuery ) { 2 3 // String to Object flags format cache 4 var flagsCache = {}; 5 6 // Convert String-formatted flags into Object-formatted ones and store in cache 7 // 将字符串形式的flags转换成对象形式,并且存到cache中,例: "once memory" => {"once&

jQuery -&gt; Callbacks

Callbacks 是jQuery 1.7之后新加的一个工具,用于管理callback lists(函数数组) 作为码农,经常被灌输这样的逻辑: 真正厉害的不是写多么复杂的代码,而是写简单易懂的代码. 不明就里的人则会把她作为衡量代码质量的准则,并抓住每一个抱怨的机会说道,"这代码真复杂,是给人看的吗!". 关于Callbacks的基本使用,可以移步到Callbacks API 下面说一下创建Callbacks对象时使用的四个参数类型 once 确保只能fire一次,由全局变量fire

jQuery.Callbacks之demo

jQuery.Callbacks是jquery在1.7版本之后加入的,是从1.6版中的_Deferred对象中抽离的,主要用来进行函数队 列的add.remove.fire.lock等操作,并提供once.memory.unique.stopOnFalse四个option进行一些特 殊的控制,这是jquery的官方文档:http://api.jquery.com/jQuery.Callbacks/ 这个函数常见的应用场景是事件触发机制,也就是设计模式中的观察者(发布.订阅机制),目前Callba

jQuery回调、递延对象总结(一)jQuery.Callbacks详解

前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数,或作为ajax发送请求,应用于请求各种状态的处理,我们可以称为异步回调,jQuery.Callbacks 为我们封装了一个回调对象模块,我们先来看一个应用场景: // 为什么jQuery中的ready事件可以执行多个回调,这得益于我们的jQuery.Deferred递延对象(是基于jQuery.Ca

jquery Callbacks方法实现

版本:1.7.1 jQuery.Callbacks(flags) 调用Callbacks方法后,返回一个用于处理回调函数队列的对象,对象包含有add,remove,fire,fireWith,fired,lock,locked,disable, disabled,has,empty方法用于管理和操作回调函数队列,回调函数队列以数组的形式存储在函数Callbacks作用域内,通过闭包机制返回的回调对象操作回调函数队列. 参数flags 取值:once memory unique stopOnFal

jQuery Callbacks应用关键点

Callbacks是jQuery 1.7引入的方法,用于管理一系列使用相同参数的回调函数.所有回调函数(以下简称回调)保存在一个数组中,可以重复调用.其本质相当于一个回调函数列(List),因此可以做添加.删除.清空回调函数等操作. 生成回调列(Callbacks) var callbacks = $.Callbacks(); 回调执行顺序 回调保存在数组中,然后通过for循环遍历,所以列中的回调按照被添加的顺序依次执行,最后添加的一般最后执行. // Fire the items on the

观察者模式 与 jQuery.Callbacks

var Subscriber = function(){ var subName = arguments[0]; return function(){ console.log("我是"+subName,"我收到了"+arguments[0]); } }; var XM = Subscriber("小明"); var XA = Subscriber("小暗"); var pub_sub = function(){ var sub

jQuery 源码callbacks

callbacks工具方法,作用是函数回调的统一管理 jQuery.Callbacks = function( options ) { } 使用:类似于事件绑定,fire之后,之前绑定的方法,都执行. 观察者模式. function aaa() { alert(1); } function bbb() { alert(2); } function ccc() { alert(3) } var cb = $.Callbacks(); cb.add(aaa); cb.add(bbb); cb.add

jquery源码01---(2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理

// optionsCache : { 'once memory' : { once : true , memory : true } } var optionsCache = {}; // once memory,options.match( core_rnotwhite )=[once, memory],function( _, flag )={once:true,memory:true} function createOptions( options ) { var object = op