jQuery Callbacks源码分析

Callbacks基本语法

描述

  1. $.Callbacks是用于jQuery内部管理函数队列,为$.Defferred等组件提供基础功能函数
  2. 经过add添加处理函数到队列当中,fire执行这些处理函数
var cb = $.Callbacks()
cb.add(function(){
  console.log(123)
})
cb.fire()  //123
复制代码

$.Callbacks能够接受字符串传参的形式,接受四种特定的功能java

  1. $.Callbacks('once')
  2. $.Callbacks('unique')
  3. $.Callbacks('stopOnFalse')
  4. $.Callbacks('memory')
  5. 支持 $.Callbacks('memory stopOnFalse') 多参数传参

once

// 添加参数once,函数队列只执行一次,fire只执行一次
var cb = $.Callbacks('once')
cb.add(function(){
  console.log(123)
})
cb.fire()  //123
cb.fire()  //由于添加了once,该方法不执行
复制代码

unique

// 添加参数unique,添加函数保持惟一,不能重复添加
var cb = $.Callbacks('unique')
function demo(){
    console.log(123)
}
cb.add(demo)
cb.add(demo)
cb.fire()  //123 当不添加unique,此处打印两个123
复制代码

stopOnFalse

// 添加参数stopOnFalse,内部函数依次执行,当某个函数返回false时,中止执行剩余函数
var cb = $.Callbacks('stopOnFalse')
cb.add(function(){
  console.log(111)
  return false
},funcion(){
  console.log(222)
})
cb.fire()  //111
复制代码

memory

// 添加参数memory,当函数队列fire一次以后,内部会记录当前fire的参数。当下次调用add的时候,会把记录的参数传递给新添加的函数并当即执行这个新添加的函数
var cb = $.Callbacks('memory')
cb.add(function(){
  console.log(111)
})
cb.fire()  //111
cb.add(function(){
  console.log(222)
})  //222 没有执行fire方法也会打印222
复制代码

实现

(function(root){
    var optionsCache = {}
    var _ = {
        callbacks: function(options){
            options = typeof options === "string" ? (optionsCache[options] || createOptions(options)) : {}
            var list = []   //储存函数
            var index,length,testting,memory,start,starts
            var fire = function(data){
                length = list.length
                index = starts || 0
                //控制memory参数,将data赋值给memory
                memory = options.memory && data
                testting = true
                for(; index < length; index++){
                    //控制stopOnFalse参数,若是函数返回false,则retun
                    if(list[index].apply(data[0],data[1]) === false && options.stopOnFalse){
                        break
                    }
                }
            }
            var self = {
                //将传进来的方法放入list队列中
                add(){
                    start = list.length;
                    [...arguments].forEach((fn)=>{
                        if(toString.call(fn)==="[object Function]"){
                            //控制unique参数
                            if(!options.unique || list.indexOf(fn) <= -1){
                                list.push(fn)
                            }
                        }
                    })
                    if(memory){
                        starts = start
                        fire(memory)
                    }
                },
                //控制上下文的对象
                fireWith(content, arguments){
                    //控制once参数
                    if(!options.once || !testting){
                        fire([content, arguments])
                    }
                },
                //控制参数的传递
                fire(){
                    self.fireWith(this, arguments)
                }
            }
            return self
        }
    }

    //接受参数,支持多个参数传递,将其保存到optionsCache缓存里面
    function createOptions(options){
        var object = optionsCache[options] = {}
        options.split(/\s+/).forEach(value => {
            object[value] = true
        })
        return object
    }

    root._ = _
})(this)
复制代码
相关文章
相关标签/搜索