使用 q 服務的 Angular 承諾
$q
是一個內建服務,它有助於執行非同步函式並在完成處理時使用它們的返回值(或異常)。
$q
與 $rootScope.Scope
模型觀察機制整合,這意味著更快地將解析度或拒絕傳播到模型中,避免不必要的瀏覽器重繪,這將導致 UI 閃爍。
在我們的例子中,我們呼叫我們的工廠 getMyData
,它返回一個 promise 物件。如果物件是 resolved
,則返回一個隨機數。如果是 rejected
,它會在 2 秒後返回拒絕並顯示錯誤訊息。
在 Angular 工廠
function getMyData($timeout, $q) {
return function() {
// simulated async function
var promise = $timeout(function() {
if(Math.round(Math.random())) {
return 'data received!'
} else {
return $q.reject('oh no an error! try again')
}
}, 2000);
return promise;
}
}
在呼叫中使用 Promise
angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
var promise = getData()
.then(function(string) {
console.log(string)
}, function(error) {
console.error(error)
})
.finally(function() {
console.log('Finished at:', new Date())
})
})
要使用 promises,請將 $q
注入依賴項。我們在 getMyData
工廠注入了 $q
。
var defer = $q.defer();
通過呼叫 $q.defer()
構造一個新的 deferred 例項
延遲物件只是一個公開 promise 的物件,以及解析該 promise 的相關方法。它使用 $q.deferred()
函式構建,並暴露出三種主要方法:resolve()
,reject()
和 notify()
。
resolve(value)
- 使用值解析派生的 promise。reject(reason)
- 拒絕派生的承諾。notify(value)
- 提供有關承諾執行狀態的更新。在承諾被解決或拒絕之前,可以多次呼叫此方法。
屬性
通過 promise 屬性訪問關聯的 promise 物件。promise
- {Promise} - 與此延遲相關聯的 promise 物件。
建立延遲例項時會建立一個新的 promise 例項,並可以通過呼叫 deferred.promise
來檢索。
promise
物件的目的是允許感興趣的各方在完成時訪問延遲任務的結果。
承諾方法 -
-
then(successCallback, [errorCallback], [notifyCallback])
- 無論何時或將要解決或拒絕承諾,只要結果可用,就會非同步呼叫其中一個成功或錯誤回撥。使用單個引數呼叫回撥:結果或拒絕原因。另外,在解決或拒絕承諾之前,可以將通知回撥呼叫零次或多次以提供進度指示。 -
catch(errorCallback)
- promise.then 的簡寫(null, errorCallback) -
finally(callback, notifyCallback)
- 允許你觀察承諾的履行或拒絕,但是在不修改最終值的情況下這樣做。
承諾最強大的功能之一是將它們連結在一起的能力。這允許資料流過鏈並在每一步被操作和變異。以下示例演示了這一點:
例 1:
// Creates a promise that when resolved, returns 4.
function getNumbers() {
var promise = $timeout(function() {
return 4;
}, 1000);
return promise;
}
// Resolve getNumbers() and chain subsequent then() calls to decrement
// initial number from 4 to 0 and then output a string.
getNumbers()
.then(function(num) {
// 4
console.log(num);
return --num;
})
.then(function (num) {
// 3
console.log(num);
return --num;
})
.then(function (num) {
// 2
console.log(num);
return --num;
})
.then(function (num) {
// 1
console.log(num);
return --num;
})
.then(function (num) {
// 0
console.log(num);
return 'And we are done!';
})
.then(function (text) {
// "And we are done!"
console.log(text);
});