开发者社区> 野兽''> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

AngularJs $q 承诺与延迟

简介: $q 一个帮助处理异步执行函数的服务。当他们做完处理时,使用它们的返回值(或异常)。 受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用。 $q的两种方式---这是一个更类似于Kris Kowal Q或jQuery的递延实现,另一种在一定程度上类似的ES6承诺。
+关注继续查看

$q

一个帮助处理异步执行函数的服务。当他们做完处理时,使用它们的返回值(或异常)。

受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用。

$q的两种方式---这是一个更类似于Kris Kowal Q或jQuery的递延实现,另一种在一定程度上类似的ES6承诺。

Deferred Api

一个被$q.defer()调用的deferred的新实例。

deferred对象的目的是暴露相关承诺实例,以及APIs被执行的成功或不成功情况,以及任务的状态。

方法

resolve(value):根据value以解决派生的promise。如果值是通过$q.reject构造的rejection 对象,该promise将被拒绝。

reject(reason):根据reason以拒绝派生的promise。这相当通过 $q.reject构造的rejection 对象来解决。

notify(value):在 promise 被执行的过程中提供状态更新情况。这可能会被多次调用,在promise是被解决还是被拒绝之前。

属性

promise:承诺,与这个延迟相关的承诺对象。

 

Promise Api

当一个deferred实例被创建时,一个promise实例被创建,并且可以通过调用deferred.promise检索。Promise对象的目的是当它完成后允许需要的地方获得延迟任务的结果。

方法

then(successCallback,errorCallback,notifyCallback);

无论什么时候,promise是已经(将要)被解决或拒绝,只要结果是可用的,就调用一个成功/错误的回调异步。回调函数带着一个参数被调用:解决的结果或拒绝的原因。此外,在承诺被解决或被拒绝之前,通知回调可能被调用0或多次用来提供一个指示进度。

这个方法返回被successCallback/errorCallback的解决或拒绝的返回值作为一个新的承诺(除非返回值是个promise,在承诺链的承诺和值都被解决的情况下)。它还将通过notifycallback方法的返回值进行通知。promise 不能从notifyCallback方法得到解决或拒绝 。

catch(errorCallback);

promise.then(null, errorCallback) 的快捷方式。

finally(callback,notifyCallback);

允许你观察一个承诺的解决或拒绝,但这样做不能修改最后的值。这可用于promise不论是被解决或拒绝后释放资源或做一些清理。

链式承诺

因为调用本次promise的方法将会返回一个新的延生的promise,它很容易创建一个承诺链:

  promise = promise.then(function(result){  return  result+1;  });

当一个承诺解决另一个承诺(这将推迟其进一步的解决)可能创建一个任何长度的链。它可能在链中的任何处暂停/推迟承诺。这使得它可以像$http的响应拦截这类强大的API。

Kris Kowal’s Q和$q的不同

以下是两个主要的不同:

在Angular里,$q和$rootScope.Scope Scope模型的观察机制集成,这意味着更快的将解决/拒绝的结果传播到你的model和避免不必要的浏览器重新渲染(这将导致ui的闪烁)。

Q比$q有更多的特性,但这是以字节为代价的。$q是小版本的,但包含所有常见的异步任务所重要的功能。

依赖:$rootScope

使用:$q(resolver);

方法

defer();

创建一个deferred对象,它代表一个将在将来完成的任务。返回一个deferred的新实例。

reject(reason);

创建一个由指定的理由拒绝的承诺。在承诺链中,这个api将被用于承诺的拒绝。如果你正在处理一个承诺链的最后一个承诺,那么你不需要担心它。

reason:常数,消息,异常或一个对象表示拒绝原因。

返回一个已经根据拒绝原因解决了的承诺。

when(value);

将一个对象或者一个值或者一个第三方承诺包装进$q承诺。当你处理一个可能是承诺或可能不是承诺或承诺来自一个不可信的来源的对象。

value:值或者承诺。

返回一个承诺。

resolve(value);

when的别名,为了与ES6保持一致。

all(promises);

当所有承诺都得到解决后,在一个单一的承诺里集合多个被解决的承诺。

promises:承诺的数组或者哈希。

返回一个将被结合一个数组/哈希或者值解决的单一的承诺,每个值在相同索引/键的数组/哈希承诺对应相对承诺,如果有任何承诺被拒绝,这将导致承诺被以相同的拒绝值拒绝。

使用代码:

  (function () {
      angular.module('Demo', [])
      .controller('testCtrl', ["$q", testCtrl]);
      function testCtrl($q) {
          var fn = function (value) {
              var defer = $q.defer();
              if (value == "Hello") {
                  defer.resolve("Hello World");
              } else {
                  defer.reject("hello world");
              }
              return defer.promise;
          };
          var promise = fn("Hello");
          promise.then(function (v) {
              console.log("resolved with " + v);
          }, function (r) {
              console.log("rejected with " + r);
          });//Hello World
          var anotherPromise = fn();
          anotherPromise.then(function (v) {
              console.log("resolved with " + v);
          }, function (r) {
              console.log("rejected with " + r);
          });//hello world
      }
  }());

承诺

  (function () {
      angular.module('Demo', [])
      .controller('testCtrl', ["$q", testCtrl]);
      function testCtrl($q) {
          var fnA = function (value) {
              var defer = $q.defer();
              if (value == "Hello") {
                  defer.resolve("Hello World -- fnA");
              } else {
                  defer.reject("hello world -- fnA");
              }
              return defer.promise;
          };
          var fnB = function (value) {
              var defer = $q.defer();
              if (value == "Hello") {
                  defer.resolve("Hello World -- fnB");
              } else {
                  defer.reject("hello world -- fnB");
              }
              return defer.promise;
          };
          var promise = fnA("Hello");
          promise.then(function (v) {
              console.log("resolved with " + v);//Hello World -- fnA
              return fnB();
          }, function (r) {
              console.log("rejected with " + r);
              return fnB("Hello");
          }).then(function (v) {
              console.log("resolved with " + v);
          }, function (r) {
              console.log("rejected with " + r);//hello world -- fnB
          })
      }
  }());

.when():

  (function () {
      angular.module('Demo', [])
      .controller('testCtrl', ["$q", testCtrl]);
      function testCtrl($q) {
          var obj = { value: "Hello World" };
          $q.when(obj.value).then(function (v) {
              console.log(v);// Hello World
              obj = { text: "hello world" }
              return $q.when(obj.text);
          }).then(function (v) {
              console.log(v);// hello world
          })
      }
  }());

.all():

  (function () {
      angular.module('Demo', [])
      .controller('testCtrl', ["$q", testCtrl]);
      function testCtrl($q) {
          var fnA = function (value) {
              var defer = $q.defer();
              if (value == "Hello") {
                  defer.resolve("Hello World -- fnA");
              } else {
                  defer.reject("hello world -- fnA");
              }
              return defer.promise;
          };
          var fnB = function (value) {
              var defer = $q.defer();
              if (value == "Hello") {
                  defer.resolve("Hello World -- fnB");
              } else {
                  defer.reject("hello world -- fnB");
              }
              return defer.promise;
          };
          var promiseA = fnA("Hello").then(function (v) {
              console.log("resolved with " + v);
              return fnB();
          }, function (r) {
              console.log("rejected with " + r);
              return fnB("Hello");
          });
          var promiseB = fnB().then(function (v) {
              console.log("resolved with " + v);
          }, function (r) {
              console.log("rejected with " + r);
          });
          var promises = [promiseA, promiseB];
          $q.all(promises);
          /*  result:
          **  resolved with Hello World -- fnA 
          **  rejected with hello world -- fnB
          */
      }
  }());

关于$q,本兽目前的理解也就这些,用的话也是看情况着用,更多时候觉得它就像语法糖一般,只是省了N多嵌套,但不得不说这个语法糖让代码可读性和整洁性好了很多。$q更多的好处是在promise和deferred,创建个承诺,在后面需要的地方再回来解决这个承诺。同时也推荐一篇关于描述$q的文章,雪狼大叔写的,url是:http://www.ngnice.com/posts/126ee9cf6ddb68 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
在AngularJS应用中实现认证授权
在AngularJS应用中实现认证授权 在每一个严肃的应用中,认证和授权都是非常重要的一个部分。单页应用也不例外。应用并不会将所有的数据和功能都 暴露给所有的用户。用户需要通过认证和授权来查看应用的某个特定部分,或者在应用中进行特定的行为。
1035 0
AngularJs-变量
Angularjs-变量 名字 : Hello {{name}} ...
524 0
AngularJs angular.Module模块接口配置
angular.Module Angular模块配置接口。 方法: provider(name,providerType); name:服务名称。 providerType:创建一个服务的实例的构造函数。
499 0
云服务器ECS与智能家居
学校实习那些事儿
0 0
AngularJS----服务,表单,模块
AngularJS----服务,表单,模块
0 0
+关注
野兽''
只要是代码就好
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Angular从零到一
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载