$q in Angular [ngdoc service] 翻译
2017-05-08 19:02
344 查看
[TOC]
从错误处理的角度看,
一开始,引人这种额外的复杂性,其效果可能是不明显的。 当执行顺序按照
另外
promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。
这个方法会返回一个新的
因为在 ES3 版本的 JavaScript 中
我们可以创建任意长度的
Kris Kowal's Q 与 \(q 之间的区别 主要区别有两点: Angular中的 `\)q
创建一个
返回 {Deferred} 返回一个新实例的
$q# reject(reason)
创建一个被特定的原因 rejected 的
把
参数: reason
类型: *
描述: Constant, message, exception 或代表拒绝原因的 object。
返回: Promise 返回一个promise ,已经因为 reason 而被拒绝了 。
when(value)
将一个对象(可能是value 或 [第三方]then-able promise) 包装为一个 $q promise。 这在你不确定所处理的对象是否是一个promise 时是很有用的,有可能该对象来自于一个不被信任的源头。
参数: value
类型: *
描述: promise 的值
返回 Promise 根据传入的值/或promise 返回一个包装后的 promise
all(promises)
合并多个
参数: promises
类型: Array.
promise / deferred实现的灵感来自于 [Kris Kowal's Q][1] - [The CommonJS Promise proposal][2] (CommonJS Promise建议文档)描述了将
promise作为一个接口,用来与异步执行操作
(action)的结果对象进行交互,该操作
(action)在给定时间内可能或不可能完成(如超时,错误,拦截等等)。
从错误处理的角度看,
deferred与
promiseAPIs 对于异步编程, 等同于同步编程的
try、
catch以及
throw关键字.
// 在本例中,假设 `$q`, `scope` 以及 `okToGreet` 在当前执行环境中是可用的 // (如它们已经被注入,或者作为参数传递进来). function asyncGreet(name) { var deferred = $q.defer(); setTimeout(function () { deferred.notify('About to greet ' + name + '.'); if (okToGreet(name)) { deferred.resolve('Hello, ' + name + '!'); } else { deferred.reject('Greeting ' + name + ' is not allowed.'); } }, 1000); return deferred.promise; } var promise = asyncGreet('Robin Hood'); promise.then(function (greeting) { alert('Success: ' + greeting); }, function (reason) { alert('Failed: ' + reason); }, function (update) { alert('Got notification: ' + update); });
一开始,引人这种额外的复杂性,其效果可能是不明显的。 当执行顺序按照
promise和
deferredAPIs 确定的那样,其优点就显现出来了。请参考: [https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md][3]
另外
promise api可以实现在传统的回调([CPS][4])方法中难以实现的组合方式。 更多信息请查阅 [Q文档][5] ,尤其是 [串行与并行结合promises][6] 的章节。
Deferred API
通过调用$q.defer()可以构造一个新的
deffered实例。
deffered对象是将
Promise实例与 可以用来标记任务状态(执行是否成功)的 APIs 相关联。
deffered 对象的方法
resolve(value)—— 传入
value解决派生的
promise。 如果
value是一个通过
$q.reject构造的拒绝对象(rejection) , 该
promise将被拒绝。
reject(reason)—— 拒绝派生的
promise,并给出原因。这相当于通过
$q.reject构造的拒绝对象(rejection) 作为参数传递给
resolve。
notify(value)—— 在
promise执行的过程中提供状态更新。这在
promise被解决或拒绝之前可能会被多次调用。
deffered 对象的属性
promise–
{Promise}—— 与延迟(deferred)相关联的
promise对象。
Promise API
当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过 deferred.promise 得到该引用。promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。
promise 对象的方法
then(successCallback, errorCallback, notifyCallback)—— 不管
promise是被处理还是被拒绝, 一旦结果(the result)可用,
then就会尽快地异步调用. 回调函数被调用时会传递进一个参数: 结果(the result)或者拒绝的理由(reject reason)。此外,在
promise被 reslove 或 reject 之前,
notify回调可能被调用
0到多次,以提供一个进度的指示。
这个方法会返回一个新的
promise对象,该对象根据
successCallback与
errorCallback的返回值表示是被 resolved 或 rejected 。 它还通过
notifyCallback方法的返回值进行通知。
promise不能从
notifyCallback方法得知是被 resloved 还是 rejected.
catch(errorCallback)——
promise.then(null, errorCallback)的快捷方式.
finally(callback)—— 让你可以观察到一个
promise是被执行还是被拒绝,但这样做不允许修改最后的
value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管
promise是被 resolved 还是rejected. 更多的信息[请参阅完整文档规范][7].
因为在 ES3 版本的 JavaScript 中
finally是一个保留字,不能作为属性名,所以为了兼容 IE8 与 Andriod 2.x, 需要借助
promise['finally'](callback)这种形式来调用该方法。
Chaining promises | 创建promise链
因为调用一个promise的
then方法返回一个新的派生
promise实例,所以创建
promises链也是很容易的:
promiseB = promiseA.then(function(result) { return result + 1; }); // promiseB 将会在处理完 promiseA 之后立即被处理, // 并且其 value 值是 promiseA 的结果增加 1
我们可以创建任意长度的
promise链;因为一个
promise可以被另一个
promise处理(进一步推迟解决完成时间),所以在
promise链上的任意一点进行
阻塞/延迟(pause/defer)都是可行的。这使得实现如
$http响应拦截器这样功能强大的 APIs 成为现实.
Kris Kowal's Q 与 \(q 之间的区别 主要区别有两点: Angular中的 `\)q集成了 {@link ng.$rootScope.Scope}
Scope模型观察机制,这意味着解决或拒绝的结果会以更快地传播速度反映在数据模型中(model),避免不必要的浏览器重绘,因为重绘会导致UI闪烁.
Q比
\(q` 拥有更多的功能特性,但也带来了代码字节数的增加。`\)q` 虽然是轻量级的,但包含了一般的异步任务所需的所有重要功能。
it('should simulate promise', inject(function($q, $rootScope) { var deferred = $q.defer(); var promise = deferred.promise; var resolvedValue; promise.then(function(value) { resolvedValue = value; }); expect(resolvedValue).toBeUndefined(); // 模拟 promise 的 resolving deferred.resolve(123); // 注意 'then' function 不是同步调用的. // 因为我们需要 promise API 一直是异步的(async), // 不管是在同步调用还是异步调用中都是如此. expect(resolvedValue).toBeUndefined(); // 使用 $apply()将 promise resolution 传递到 'then' functions . $rootScope.$apply(); expect(resolvedValue).toEqual(123); }));
Dependencies
$rootScopeMethods
$q# defer()创建一个
递延(Deferred)对象表示一个将来要完成任务.
返回 {Deferred} 返回一个新实例的
Deferred.
$q# reject(reason)
创建一个被特定的原因 rejected 的
promise. 此 api 应该用于在一个
promises链中进行转发(?) rejection。如果你正在处理
promise链中的最后一个
promise,你就不用担心它。
把
deferreds/promises与我们熟悉的的
try/catch/throw行为进行对比,可以认为
reject相当于 JavaScript 中的
throw关键字。这也意味着如果你通过一个
promise的
error回调,
"catch"了一个错误,而且你想要从当前的
promise中转发这个
error到派生的
promise中,就必须通过返回的
rejection(由 reject 构造的),重新抛出(rethrow)这个
error。
promiseB = promiseA.then(function(result) { // success: 此处可以执行某些操作,然后直接使用原有的result, // 或者对result进行操作,来处理接下来的promiseB return result; }, function(reason) { // error: handle the error if possible and // resolve promiseB with newPromiseOrValue, // 否则转向拒绝 promiseB 的分支 if (canHandle(reason)) { // 处理错误和恢复 return newPromiseOrValue; } return $q.reject(reason); });
参数: reason
类型: *
描述: Constant, message, exception 或代表拒绝原因的 object。
返回: Promise 返回一个promise ,已经因为 reason 而被拒绝了 。
when(value)
将一个对象(可能是value 或 [第三方]then-able promise) 包装为一个 $q promise。 这在你不确定所处理的对象是否是一个promise 时是很有用的,有可能该对象来自于一个不被信任的源头。
参数: value
类型: *
描述: promise 的值
返回 Promise 根据传入的值/或promise 返回一个包装后的 promise
all(promises)
合并多个
promises为单个
promise,在所有输入的
promise都处理之后,组合之后的
promise才会处理完成。
参数: promises
类型: Array.
相关文章推荐
- $q in Angular [ngdoc service]
- 翻译作品一之Service Banner Fingerprinting in C
- 《Service Oreiented Architecture in the Real World》推荐及翻译计划
- 翻译作品一之Service Banner Fingerprinting in C
- NServiceBus翻译之持久化技术(一):Persistence In NServiceBus
- Part 17 Consuming ASP NET Web Service in AngularJS using $http
- Part 18 $http service in AngularJS
- Part 20 Create custom service in AngularJS
- [Angular Directive] Build a Directive that Tracks User Events in a Service in Angular 2
- [Angular] Using the Argon 2 Hashing Function In Our Sign Up Backend Service
- [Angular Directive] Create a Template Storage Service in Angular 2
- [Angular 2] Handle Reactive Async opreations in Service
- 翻译:Announcing Zuul: Edge Service in the Cloud
- NServiceBus翻译之持久化技术(二):Using RavenDB In NServiceBus – Installing
- 我也谈“the difference between Factory, Service, and Provider in Angular”
- How to call a service function in AngularJS ng-click
- Service and controller in angularJs
- NServiceBus翻译之持久化技术(三):Using RavenDB In NServiceBus – Connecting
- Angularjs accessing methods in another factory/service
- Angular build Error:In this configuration Angular requires Zone.js