淺談Angular的 $q, defer, promise

1. $q

$q是Angular的一種內置服務,它可以使你異步地執行函數,並且當函數執行完成時它允許你使用函數的返回值(或異常)。

2. defer

defer的字面意思是延遲, $q.defer()  可以創建一個deferred實例(延遲對象實例)。

deferred 實例旨在暴露派生的Promise 實例,以及被用來作爲成功完成或未成功完成的信號API,以及當前任務的狀態。這聽起來好複雜的樣子,總結$q, defer, promise三者之間的關係如下所示。

var deferred = $q.defer();  //通過$q服務註冊一個延遲對象 deferred
var promise = deferred.promise;  //通過deferred延遲對象,可以得到一個承諾promise,而promise會返回當前任務的完成結果

defer的方法:

1. deferred.resolve(value)  成功解決(resolve)了其派生的promise。參數value將來會被用作promise.then(successCallback(value){...}, errorCallback(reason){...}, notifyCallback(notify){...})中successCallback函數的參數。

2. deferred.reject(reason)  未成功解決其派生的promise。參數reason被用來說明未成功的原因。此時deferred實例的promise對象將會捕獲一個任務未成功執行的錯誤,promise.catch(errorCallback(reason){...})。補充一點,promise.catch(errorCallback)實際上就是promise.then(null, errorCallback)的簡寫。

3. notify(value)  更新promise的執行狀態(翻譯的不好,原話是provides updates on the status of the promise's execution)

defer的小例子:

function asyncGreet(name) {
  var deferred = $q.defer();  //通過$q.defer()創建一個deferred延遲對象,在創建一個deferred實例時,也會創建出來一個派生的promise對象,使用deferred.promise就可以檢索到派生的promise。

  deferred.notify('About to greet ' + name + '.');  //延遲對象的notify方法。

  if (okToGreet(name)) {
    deferred.resolve('Hello, ' + name + '!');  //任務被成功執行
  } else {
    deferred.reject('Greeting ' + name + ' is not allowed.');  //任務未被成功執行
  }

  return deferred.promise;  //返回deferred實例的promise對象
}

function okToGreet(name) {
  //只是mock數據,實際情況將根據相關業務實現代碼
  if(name == 'Superman') return true;  
  else return false;
}

var promise = asyncGreet('Superman');  //獲得promise對象
//promise對象的then函數會獲得當前任務也就是當前deferred延遲實例的執行狀態。它的三個回調函數分別會在resolve(), reject() 和notify()時被執行
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
}, function(update) {
  alert('Got notification: ' + update);
});

3. promise

當創建一個deferred實例時,promise實例也會被創建。通過deferred.promise就可以檢索到deferred派生的promise。

promise的目的是允許interested parties 訪問deferred任務完成的結果。

按照CommonJS的約定,promise是一個與對象交互的接口,表示一個動作(action)的結果是異步的,而且在任何給定的時間點上可能或不可能完成。(這句話好繞口,我的理解是promise相當於一個承諾,承諾你這個任務在給定的時間點上可能會完成,也可能完成不了。如果完成了那就相當於resolve, 如果未完成就相當於reject。不知道這樣理解對不對?)

promise 的方法:

1. then(successCallback, errorCallback, nitifyCallback) 根據promise被resolve/reject,或將要被resolve/reject,調用successCallback/errorCallback。

2. catch(errorCallback)  then(null, errorCallback)的縮寫。

3. finally(callback, notifyCallback)

補充說明:

promise.then()會返回一個新的衍生promise,形成promise鏈。例如:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章