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