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)
複製代碼
相關文章
相關標籤/搜索