加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

$q -- AngularJS中的服务

发布时间:2020-12-17 10:05:51 所属栏目:安全 来源:网络整理
导读:原文链接: $q 官方文档 描述 既然是用来处理异步编程的,那么在浏览器端的JS里,主要是2种: setTimeout 和 Ajax 请求. promise 的使用就很像Ajax请求的成功和失败回调。 此承诺/延迟(promise/deferred)实现的灵感来自于 Kris Kowal's QCommonJS Promise建议
原文链接: $q 官方文档


描述

既然是用来处理异步编程的,那么在浏览器端的JS里,主要是2种: setTimeout 和 Ajax 请求. promise 的使用就很像Ajax请求的成功和失败回调。


此承诺/延迟(promise/deferred)实现的灵感来自于 Kris Kowal's QCommonJS Promise建议文档将承诺(promise) 作为和 异步执行操作(action)结果对象进行交互的接口,在指定的时间内可能完成也可能不能够完成(如超时,错误,拦截等等)。

从错误处理的角度看,延迟( deferred)和承诺( promise) API 对于异步编程来说,和同步编程的 try,catch,以及 throw作用差不多.
[javascript] view plain copy
  1. //为了演示的目的,此处我们假设`$q`,`scope`以及`okToGreet`引用在当前执行环境中可用
  2. //(比如他们已经被注入,或者被当做参数传进来了).
  3. functionasyncGreet(name){
  4. vardeferred=$q.defer();
  5. setTimeout(function(){
  6. //因为此function在未来的事件循环中异步执行,
  7. //我们需要把代码包装到到一个$apply调用中,以便正确的观察到model的改变
  8. scope.$apply(function(){
  9. deferred.notify('即将问候'+name+'.');
  10. if(okToGreet(name)){
  11. deferred.resolve('你好,'+name+'!');
  12. }else{
  13. deferred.reject('拒绝问候'+name+'.');
  14. }
  15. });
  16. },1000);
  17. returndeferred.promise;
  18. }
  19. varpromise=asyncGreet('小漠漠');
  20. promise.then(function(greeting){
  21. alert('成功:'+greeting);
  22. function(reason){
  23. alert('失败鸟:'+reason);
  24. function(update){
  25. alert('收到通知:'+update);
  26. });

引人这种额外的复杂性的效果 在起初可能不明显。 在 promise 和 deferred APIs 进行承诺时好处就看出来了,请参考: https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md
另外 promise api允许那些在传统的回调( CPS )方法中很难的实现的组合。 更多信息请查阅 Q文档,特别是 串行与并行的合并一节。

延迟接口 | Deferred API

通过调用 $q.defer() 可以构建一个新的 deffered 实例。
deffered 对象用来将 Promise 实例与 标记任务状态(执行成功还是不成功)的 API 相关联。

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 是被处理还是被拒绝,一旦结果可用,then 就会尽快地异步调用 成功/错误 回调函数 只要结果是可用的。 调用回调函数时传递单个参数: 结果 或拒绝的理由。 此外,notify 回调可能被调用 0到多次,以提供 提供一个进度指示,之前承诺解决或拒绝。
这个方法 返回一个新的promise 对象,根据 successCallback,errorCallback的返回值进行解决或拒绝 。 它还通过 notifyCallback 方法的返回值进行通知。 promise 不能从notifyCallback方法得到解决或拒绝 。
  • catch(errorCallback) —— promise.then(null,errorCallback) 的快捷方式
  • finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝,但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。 更多的信息请参阅完整文档规范.
因为在 ES3版本的JavaScript中 finally 是一个保留字关键字,不能作为属性名,为了适配 IE8,您需要使用 promise['finally'](callback) 这种形式来调用该方法。

promise 链 | Chaining promises

因为调用一个 promise 的 then 方法返回一个新的派生 promise实例,所以构建promises链也是很容易的:
copy
promiseB=promiseA.then(function(result){
  • returnresult+1;
  • });
  • //promiseB将会在处理完promiseA之后立刻被处理,
  • //并且其value值是promiseA的结果增加1
  • 我们可以创建任意长度的promise链;因为一个promise可以被另一个promises处理(进一步推迟解决完成时间),所以在promise链上的任意一点进行 暂停/推迟解决 都是可行的。 这使得实现功能强大的APIs 成为现实,例如 $http的响应拦截器。

    Kris Kowal's Q 与 $q 之间的区别

    主要区别有两点:
    • Angular中的$q 集成了 ng.$rootScope.Scope Scope模型观察机制,这意味着对models 的解决或拒绝速度将会更快,避免不必要的浏览器重绘(会导致UI闪烁)。
    • Q 比 $q拥有更多的功能特性,但带来的是代码字节数的增加。 $q 很轻量级,但包含了一般异步任务所需的所有重要功能。

    测试

    copy
    it('shouldsimulatepromise',inject(function($q,$rootScope){
  • vardeferred=$q.defer();
  • varpromise=deferred.promise;
  • varresolvedValue;
  • promise.then(function(value){resolvedValue=value;});
  • expect(resolvedValue).toBeUndefined();
  • //模拟promise的resolving
  • deferred.resolve(123);
  • //注意'then'function不是同步调用的.
  • //因为我们想要promiseAPI一直是异步的(async),0); background-color:inherit">//不管是在同步调用还是异步调用中都是如此.
  • expect(resolvedValue).toBeUndefined();
  • //使用$apply()将promiseresolution传递到'then'functions.
  • $rootScope.$apply();
  • expect(resolvedValue).toEqual(123);
  • }));
  • 依赖关系 | Dependencies

    $rootScope

    方法 | Methods

    all(promises)

    结合多个promises为单个promise,在所有输入的promise都处理之后,组合之后的promise才会处理完成。
    • 参数:promises
    • 类型:Array.<Promise>/Object.<Promise>
    • 描述: promises的数组或者引用
    • 返回:Promise返回单个的 promise,将与一个数组解决/散列值,每个值对应于在相同的索引/关键的承诺 承诺 /散列数组。 如果任何承诺解决排斥,这产生的承诺将被拒绝 拒绝相同的值。

    defer()

    创建一个 递延 对象代表一个将来完成任务。
    • 返回 Deferred返回一个新实例的Deferred。

    reject(reason)

    创建一个指定拒绝原因的promise. 此api应该用于在一个promises链中进行拒绝。 如果你正在处理promise 链中的最后一个promise,你不需要担心。

    把 deferreds/promises 与我们熟悉的的 try/catch/throw行为进行对比,可以认为 reject 相当于 JavaScript 中的throw 关键字。 这也意味着如果你通过一个 promise 的 error回调,“catch”了一个错误,你想要指明当前的承诺已经执行出错了,就必须重新抛出一个“附带了错误信息,拒绝通过的reject” 。
    copy
    //success:此处可以执行某些操作,然后直接使用原有的result,0); background-color:inherit">//或者对result进行操作,来处理接下来的promiseB
  • returnresult;
  • //error:handletheerrorifpossibleand
  • //resolvepromiseBwithnewPromiseOrValue,0); background-color:inherit">//否则转向拒绝promiseB的分支
  • if(canHandle(reason)){
  • //处理错误和恢复
  • returnnewPromiseOrValue;
  • 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

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读