亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

jquery.Callbacks的實現(xiàn)詳解

 更新時間:2016年11月30日 11:40:53   作者:_記憶  
這篇文章主要給大家介紹的是jQuery.Callback()的實現(xiàn),這個函數(shù)常見的應用場景是事件觸發(fā)機制,也就是設計模式中的觀察者(發(fā)布、訂閱機制),目前Callbacks對象用于queue、ajax、Deferred對象中,下面通過這篇文章來詳細看看關于jquery.Callbacks實現(xiàn)的介紹吧。

前言

jQuery.Callbacks是jquery在1.7版本之后加入的,是從1.6版中的_Deferred對象中抽離的,主要用來進行函數(shù)隊列的add、remove、fire、lock等操作,并提供once、memory、unique、stopOnFalse四個option進行一些特殊的控制。

功能介紹

jq的Callbacks模塊主要是為其他模塊提供服務的,他就像一個溫柔的小女人,在背后默默地付出。Deferred就像一個巨人,在jq中那么的突出,但在內(nèi)部,他受到Callbacks的服務。

Callbacks的幾種狀態(tài):

      once    -- 回調(diào)函數(shù)只執(zhí)行一次

      unique    -- 函數(shù)不能重復添加到回調(diào)列表中

      memory    -- 狀態(tài)記憶,主要用于Deferred中

      stopOnFalse    -- 遇到return false 終止回調(diào)列表繼續(xù)執(zhí)行

我自己實現(xiàn)的Callbacks的幾個簡單的方法

      add    -- 向對應的回調(diào)函數(shù)列表添加一個函數(shù)

      fire    -- 觸發(fā)回調(diào),回調(diào)函數(shù)列表依次執(zhí)行函數(shù)

      has    -- 回調(diào)函數(shù)列表是否存在傳入函數(shù)

      clear    -- 清空回調(diào)函數(shù)列表

整體結構

首先,我們要向得到一個想要的Callbacks模塊,需要這樣做:

var cb = Callback('memory once') // 得到一個擁有記憶功能并只執(zhí)行一次的回調(diào)模塊

由于我們需要基于一定狀態(tài)來得到不同的實例,我們可以確定,我們需要一個存儲狀態(tài)的對象

var callbackState = {}

我們給Callback函數(shù)傳入了'memory once',我們怎么記錄這兩個狀態(tài)呢,在這里,仿jq來寫的一個函數(shù)來實現(xiàn),如下:

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} ,如果狀態(tài)緩存對象里有這個對象,直接返回,沒有的話先創(chuàng)建再返回。

接下來,就是Callback函數(shù)的全部代碼了,先上代碼

var Callback = function (options) {

 var state = callbackState[options] //獲取狀態(tài)模式
 if (!state) {
  callbackState[options] = state = createCallbackState(options)
 }
 var list = [], // 回調(diào)函數(shù)列表
  memory,  // 存儲是否為 記憶狀態(tài)
  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狀態(tài)下并回調(diào)列表已經(jīng)擁有該函數(shù),則不添加
   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) { //如果函數(shù)運行返回false,并且是stopOnFalse狀態(tài),終止循環(huán)
   break;
   }
  }
  }

 return {
  add: function () {
  add.apply(null,arguments)
  // 如果memory模式并且已經(jīng)擁有了memory信息,接著出發(fā)函數(shù)
  if (state.memory && memory) {
   fire(memory[0], memory[1])
   list = []
  }
  },
  fire: function (context, args) {
  // 如果memory模式,并且list是空,代表觸發(fā)在添加前,保存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函數(shù)執(zhí)行后,返回一個對象,然后該對象包含了幾個簡單的功能。

下面我來介紹一下這部分的實現(xiàn)。

首先,如jq一樣,我也定義了內(nèi)部的add, fire, has方法,主要原因是邏輯需要,在返回對象的方法中實現(xiàn)once,memory狀態(tài)控制,內(nèi)部的add,fire方法是純粹的添加和觸發(fā)函數(shù)。

先來看cb.add方法,add方法可以接收多個函數(shù),因此

add.apply(null,arguments)

使用內(nèi)部的add做添加功能

再往下的一部分的功能是判斷這個回調(diào)模塊是否是memory狀態(tài),理解Deferred模塊的同學應該知道,該模塊是Promise模式,訂閱成功或失敗狀態(tài)的回調(diào)函數(shù),然后再某一時刻觸發(fā)他,這個模式便引用了memory狀態(tài)下的Callback,這個模式有一個奇怪的地方,如果你先發(fā)布成功,但是回調(diào)列表空空如也,那么程序并不會發(fā)布失敗,而是等待成功回調(diào)函數(shù)的加入,一但回調(diào)函數(shù)加入,立刻執(zhí)行他。

就是如下代碼

// 如果memory模式并且已經(jīng)擁有了memory信息,立刻觸發(fā)函數(shù)
 if (state.memory && memory) {
 fire(memory[0], memory[1])
 list = []
 }

提示 : ‘如果你先發(fā)布成功,但是回調(diào)列表空空如也,那么程序并不會發(fā)布失敗,而是等待成功回調(diào)函數(shù)的加入,一但回調(diào)函數(shù)加入,立刻執(zhí)行他' 的理解如下代碼

var cb = Callback('memory') // 得到記憶功能的回調(diào)模塊

cb.fire() // 觸發(fā)回調(diào)隊列

cb.add(fn) //添加回調(diào)函數(shù),自動執(zhí)行了!

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

如果在非memory狀態(tài),以上代碼無效。需要再次fire才會執(zhí)行。

經(jīng)過上述,fire函數(shù)也好理解了,fire可接收兩個參數(shù),函數(shù)上下文,函數(shù)參數(shù)數(shù)組。

與add中memory狀態(tài)的代碼連串起來,以下代碼就是fire時memory狀態(tài)下的操作

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

如果是memory狀態(tài),回調(diào)列表為空,就保存函數(shù)執(zhí)行上下文和參數(shù)數(shù)組,等add時立刻執(zhí)行。

除了上述以外,代碼就很簡單易懂啦,Callback函數(shù)就到這里了,很簡單的功能,唯一一點不好理解的就是memory狀態(tài)。

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

最新評論