成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

zepto源碼Callback

linkin / 1661人閱讀

摘要:如果回調(diào)正在進(jìn)行,則修正回調(diào)任務(wù)的長(zhǎng)度為當(dāng)前任務(wù)列表的長(zhǎng)度,以便后續(xù)添加的回調(diào)函數(shù)可以執(zhí)行。

Callback模塊是用來(lái)管理回調(diào)函數(shù),也作為deferred延遲對(duì)象得基礎(chǔ)部分,現(xiàn)在一起來(lái)看看他的源碼。
可選參數(shù):

  Options:
    once: 是否最多執(zhí)行一次,
    memory: 是否記住最近的上下文和參數(shù)
    stopOnFalse: 當(dāng)某個(gè)回調(diào)函數(shù)返回false時(shí)中斷執(zhí)行
    unique: 相同得回調(diào)只被添加一次

這是可選參數(shù),下面可以進(jìn)行試驗(yàn):

var a = function (value) {
  console.log("a:" + value);
};
var b = function (value) {
  console.log("b:" + value);
};
var callbacks = $.Callbacks();
callbacks.add(a);
callbacks.fire(["hello"]);
callbacks.add(b);
callbacks.fire("中");

下面是他的輸出結(jié)果:

a: hello,
a:中,
b:中

可以看到得是,當(dāng)我們第二次fire得時(shí)候,a函數(shù)也會(huì)執(zhí)行。
在加入?yún)?shù)進(jìn)行實(shí)驗(yàn),首先加入memory

var callbacks = $.Callbacks({
  memory: true
});
callbacks.add(a);
callbacks.fire("hello");
callbacks.add(b);
輸出:
a:hello,
b:hello

加入memory參數(shù),memory記錄上一次觸發(fā)回調(diào)函數(shù),之后添加的函數(shù)都用這參數(shù)立即執(zhí)行。在來(lái)看once的使用

var callbacks = $.Callbacks({
  once: true
});
callbacks.add(a);
callbacks.fire("hello");
callbacks.fire("中");
輸出:
a:hello

可以看到的是,雖然執(zhí)行了兩次fire方法,但是只輸出了一次結(jié)果。其他兩個(gè)參數(shù)很好理解,細(xì)節(jié)的部分自己去嘗試。

$.Callbacks = function(options) {
  options = $.extend({}, options)
  var memory, 
    fired, 
    firing,
    firingStart,
    firingLength,
    firingIndex,
    list = [],
    stack = !options.once && []
}

再看看各個(gè)參數(shù)的意義,memory會(huì)在記憶模式下記住上一次觸發(fā)的上下文和參數(shù),fired代表回調(diào)是否已經(jīng)觸發(fā)過(guò),firing表示回調(diào)正在觸發(fā),firingStart回調(diào)任務(wù)開(kāi)始的位置,firingLength回調(diào)任務(wù)的長(zhǎng)度,firingIndex當(dāng)前回調(diào)的索引,list表示真實(shí)的回調(diào)隊(duì)列,在不是觸發(fā)一次的情況下,用來(lái)緩存觸發(fā)過(guò)程中沒(méi)有執(zhí)行的任務(wù)參數(shù)。

fire = function(data) {
  memory = options.memory && data
  fired = true
  firingIndex = firingStart || 0
  firingStart = 0
  firingLength = list.length
  firing = true
  for ( ; list && firingIndex < firingLength ; ++firingIndex ) {
    if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
      memory = false
      break
    }
  }
  firing = false
  if (list) {
    if (stack) stack.length && fire(stack.shift())
    else if (memory) list.length = 0
    else Callbacks.disable()
  }
}

fire函數(shù)是唯一內(nèi)置的函數(shù),他的作用是用于觸發(fā)list的回調(diào)執(zhí)行,首先看看他傳進(jìn)的參數(shù),和咱們?cè)谕獠空{(diào)用$.Callbacks的fire還不太一樣,這里的data是一個(gè)數(shù)組,data[0]表示上下文,data[1]是方法調(diào)用的參數(shù)。然后就是各個(gè)參數(shù)的的初始化,memory表示如果options.memory為true,則保存data,fired為true,如果firingStart為0,那么firingIndex 為0,firingStart置為0,正在觸發(fā)的回調(diào)標(biāo)記firing為true。
然后遍歷回調(diào)列表,逐個(gè)執(zhí)行回調(diào),這個(gè)里邊的if判斷表示的是如果回調(diào)函數(shù)返回的是false并且options.stopOnFalse是false,則清空memory的緩存。遍歷完成后,將執(zhí)行的狀態(tài)改為false。如果list存在,stack也存在,把任務(wù)參數(shù)取出來(lái),調(diào)用fire函數(shù)執(zhí)行。如果memory存在,則清空列表,否則進(jìn)行回調(diào)執(zhí)行

最終這個(gè)文件返回的是Callbacks,我們來(lái)看看他的具體實(shí)現(xiàn):

Callbacks = {
  add: function () {
    if (list) {
      var start = list.length,
        add = function (args) {
          $.each(args, funciton(_, arg) {
            if (typeof arg === "function") {
              if (!options.unique || !Callbacks.has(arg)) list.push(arg);
            } else if (arg && arg.length && typeof arg !== "string") add(arg);
          })
        }
      add(arguments)
      if (firing) firingLength = list.length;
      else if (memory) {
        firingStart = start;
        fire(memory)
      }
    }
    return this;
  }
}

這個(gè)函數(shù)主要的作用就是像list里邊push回調(diào)。首先判斷l(xiāng)ist是否存在,如果存在,start賦值為list的長(zhǎng)度,在內(nèi)部添加一個(gè)add方法,內(nèi)部add方法主要是向list添加回調(diào),如果我們傳入的參數(shù)是數(shù)組,就再次調(diào)用add方法。然后就是調(diào)用add方法,把a(bǔ)rguments傳進(jìn)去。如果回調(diào)正在進(jìn)行,則修正回調(diào)任務(wù)的長(zhǎng)度f(wàn)iringLength為當(dāng)前任務(wù)列表的長(zhǎng)度,以便后續(xù)添加的回調(diào)函數(shù)可以執(zhí)行。如果memory存在,則把開(kāi)始設(shè)置為新添加列表的第一位,然后調(diào)用fire。
我們?cè)賮?lái)看看fireWith的做法:

fireWith: function(context, args) {
  if (list && (!fired || stack)) {
    args = args || [];
    args = [context, args.slice ? args.slice() : args];
    if (firing) stack.push(args);
    else fire(args);
  }
  return this;
}

傳入的參數(shù)包括上下文,和參數(shù)列表。函數(shù)執(zhí)行的條件是list存在并且回調(diào)沒(méi)有執(zhí)行或者stack存在,stack可以為空。首先對(duì)args進(jìn)行重新賦值,args[0]是上下文,args[1]是復(fù)制過(guò)來(lái)的列表。如果回調(diào)正在進(jìn)行,向stack里邊添加args,或者就執(zhí)行args。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96640.html

相關(guān)文章

  • Zepto源碼之fx_methods模塊

    摘要:所以模塊依賴于模塊,在引入前必須引入模塊。原有的方法分析見(jiàn)讀源碼之樣式操作方法首先調(diào)用原有的方法,將元素顯示出來(lái),這是實(shí)現(xiàn)動(dòng)畫(huà)的基本條件。如果沒(méi)有傳遞,或者為值,則表示不需要?jiǎng)赢?huà),調(diào)用原有的方法即可。 fx 模塊提供了 animate 動(dòng)畫(huà)方法,fx_methods 利用 animate 方法,提供一些常用的動(dòng)畫(huà)方法。所以 fx_methods 模塊依賴于 fx 模塊,在引入 fx_m...

    junbaor 評(píng)論0 收藏0
  • Zepto源碼之Form模塊

    摘要:模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數(shù)據(jù),另一部分是觸發(fā)事件,提交表單。最終返回的結(jié)果是一個(gè)數(shù)組,每個(gè)數(shù)組項(xiàng)為包含和屬性的對(duì)象。否則手動(dòng)綁定事件,如果沒(méi)有阻止瀏覽器的默認(rèn)事件,則在第一個(gè)表單上觸發(fā),提交表單。 Form 模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數(shù)據(jù),另一部分是觸發(fā) submit 事件,提交表單。 讀 Zepto 源碼系列文章已...

    陳江龍 評(píng)論0 收藏0
  • Zepto源碼分析(一)核心代碼分析

    摘要:源碼分析一核心代碼分析源碼分析二奇淫技巧總結(jié)本文只分析核心的部分代碼,并且在這部分代碼有刪減,但是不影響代碼的正常運(yùn)行。當(dāng)長(zhǎng)度為則不添加內(nèi)容,否則逐個(gè)將逐個(gè)到當(dāng)前實(shí)例新增直接返回一個(gè)新的構(gòu)造函數(shù)添加初始化方法。 Zepto源碼分析(一)核心代碼分析Zepto源碼分析(二)奇淫技巧總結(jié) 本文只分析核心的部分代碼,并且在這部分代碼有刪減,但是不影響代碼的正常運(yùn)行。 目錄 * 用閉包封裝Z...

    BicycleWarrior 評(píng)論0 收藏0
  • zepto 源碼之工具函數(shù)

    摘要:在遍歷的時(shí)候,還對(duì)回調(diào)函數(shù)的返回值進(jìn)行判斷,如果回調(diào)函數(shù)返回,立即中斷遍歷??梢员闅v數(shù)組類數(shù)組或?qū)ο笾械脑?,根?jù)回調(diào)函數(shù)的返回值,將返回值組成一個(gè)新的數(shù)組,并將該數(shù)組扁平化后返回,會(huì)將及排除。 Zepto 提供了豐富的工具函數(shù),下面來(lái)一一解讀。 源碼版本 本文閱讀的源碼為 zepto1.2.0 $.extend $.extend 方法可以用來(lái)擴(kuò)展目標(biāo)對(duì)象的屬性。目標(biāo)對(duì)象的同名屬性會(huì)被...

    姘擱『 評(píng)論0 收藏0
  • Zepto源碼之集合操作

    摘要:調(diào)用來(lái)獲取符合條件的集合元素,這在上篇文章讀源碼之神奇的已經(jīng)有詳細(xì)的論述。然后調(diào)用方法來(lái)合并兩個(gè)集合,用內(nèi)部方法來(lái)過(guò)濾掉重復(fù)的項(xiàng),方法在讀源碼之內(nèi)部方法已經(jīng)有論述。最后也是返回一個(gè)集合。 接下來(lái)幾個(gè)篇章,都會(huì)解讀 zepto 中的跟 dom 相關(guān)的方法,也即源碼 $.fn 對(duì)象中的方法。 讀Zepto源碼系列文章已經(jīng)放到了github上,歡迎star: reading-zepto 源碼...

    pepperwang 評(píng)論0 收藏0
  • Zepto源碼之Event模塊

    摘要:不支持事件冒泡帶來(lái)的直接后果是不能進(jìn)行事件委托,所以需要對(duì)和事件進(jìn)行模擬。調(diào)用函數(shù),分隔出參數(shù)的事件名和命名空間。這里判斷是否為函數(shù),即第一種傳參方式,調(diào)用函數(shù)的方法,將上下文對(duì)象作為的第一個(gè)參數(shù),如果存在,則與的參數(shù)合并。 Event 模塊是 Zepto 必備的模塊之一,由于對(duì) Event Api 不太熟,Event 對(duì)象也比較復(fù)雜,所以乍一看 Event 模塊的源碼,有點(diǎn)懵,細(xì)看下...

    vpants 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<