使用 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);
});