星期四, 11月 01, 2012

[jQuery] Deferred Object : Callbacks

  最近在玩 NodeJS, 然後由於 NodeJS 有child_process的操作, 不過卻都是 non-blocking的東西. 所以如果需要blocking的功能的話, 就會需要額外處理. 這時候就會想要試看看 Deferred 或是Promise 的概念, 這物件的概念代表的是當你的程序執行B是要等待A完成,再接著執行, 這聽起來Javascript 基本上都是用callback function去完成.但是callback function 太過繁瑣,而且完成的程式碼會一層包一層包一層包一層(如果有很多程序互相相關).

  就覺得應該要來看看啥是 Deferred 物件. 跑去看 Vexe'd 先生的 jQuery Deferred Object . 裏頭說道去看 jQuery 原始碼 (搜尋 Deferred: ), 發現一堆啥Callbacks("once memory").  才發現要從源頭理解 Deferred 物件運作原理,就得先從 jQuery.Callbacks下手.

  當然先從官方文件著手.大概涵義翻譯一下, 主要是提供一個callback list object, 在這個callback list object當中,我先介紹最基礎的四項操作.

  1. callbacks.add()       - 新增callback function 到 list 當中.
  2. callbacks.remove()  - 同理,就是從callback list 移除callback function.
  3. callbacks.fire()        -  觸發callback list當中的function.
  4. callbacks.disable()   -  取消掉任何之後對此callback list object 的事件觸發, fire()
  操作就是這四個動作, 然後再衍伸還有四個 Support Flags組合, 我下面使用官方案例配上 Fiddle來實作,應該會好理解很多. (按下F12開啟 debug console)


  1. 範例1 - 無任何Support Flags. 有啥東西在 callback list object 就fire()!
  2. 範例2 - once 確保這個callback list只會被fire()一次.如範例, 第一次fire()之後, 第二個fire並不會被觸發.
  3. 範例3 - memory  這個 Flags比較有趣一點, 如果新增了一個callback function之後,他會立刻觸發 fire() , 然後在觸發新的值.在範例當中看2nd add 以及 2nd  fire以及比對下方沒有設定Support Flags的執行情況,就可以很明顯知道差別.
    (在Deferred 原始碼看到很多once 跟memory的組合用法, 之後再深入理解Deferred物件後應該會知道這樣時做的原因吧.)
  4. 範例4 - unique 概念很簡單, 就是重複的callback function將只會執行一次!
  5. 範例5 - stopOnFalse 概念也不難,就是遇到 callback function回傳false時候,中斷其執行.
  說到這裡, 對於Callbacks的概念也有點清楚了, 接下來就是這些Flag交互使用, 以Deferred 物件,最常用的就是once 以及 memory. 直接翻 jQuery 的Deferred 物件.

 Deferred: function( func ) {
  var doneList = jQuery.Callbacks( "once memory" ),
      failList = jQuery.Callbacks( "once memory" ),
      progressList = jQuery.Callbacks( "memory" ),

  這邊有三個 list : doneList, failList 以及progressList. 其中doneList 跟failList 都是 once 以及memory. 稍微做了一下範例實驗, 確保doneList 跟failList 只會被若增加新的 callback function都會執行, 但是最多只能fire() 一次內容. 而 progressList 則是每次有新的callback function加入都會觸發之外, 還可以被fire() 多次.

  目前就先就 jQuery.Callbacks做個簡單介紹, 之後會進入jQuery.Deferred 物件以及Promise()方法, 這可是之後語言幾乎都會參考的一部分程式碼啊!