Angular - - $q 承诺与延迟

$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

时间: 2024-10-19 23:11:52

Angular - - $q 承诺与延迟的相关文章

野兽的Angular Api 学习、翻译及理解 - - $q 承诺与延迟

野兽的ng api学习 -- $q $q 一个帮助处理异步执行函数的服务.当他们做完处理时,使用它们的返回值(或异常). 受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用. $q的两种方式---这是一个更类似于Kris Kowal Q或jQuery的递延实现,另一种在一定程度上类似的ES6承诺. Deferred Api 一个被$q.defer()调用的deferred的新实例. deferred对象的目的是暴露相关承诺实例,以及APIs被执行的成功

C语言不完全类型与延迟定义

一直以为我的C语言学的还可以,虽说不是出神入化,但是至少比较熟悉吧.但是前一段时间看了一篇微信推文,再百度了一下C语言不完全类型.发现我居然C语言不完全类型和用途甚广的延迟定义都没概念.这两天仔细查阅了相关概念并用代码实验了一下. 本文结构如下: C语言不完全类型概念介绍 一个故事 延迟定义的优点 思考- C语言不完全类型 不完全类型也就是不知道变量的所有的类型信息.比如可以声明一个数组,但是不给出该数组的长度:声明一个指针,但是不给出该指针的类型:声明一个结构体类型,但是不给出完整的结构体定义

angularjs 缓存 $q

<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <style> #parent div{ width:300px; height:500px; b

http 资源

本文来自:http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列 1. 基础概念篇 1.1 介绍   HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1

深入理解http/https协议

深入理解HTTP协议(转) http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本.其中最著名的就是RFC 2616.RFC 2616定义了今天普

深入理解HTTP协议、HTTP协议原理分析

深入理解HTTP协议.HTTP协议原理分析 目录(?)[+] http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本.其中最著名的就是RFC 26

同步电路的setup time和hold time

在不考虑时钟的偏移和抖动问题的情况下,先来说一下单周期同步电路的时序问题.通常来说一个同步的时序电路首先要保证单个同步元器件的数据能够稳定的被采集,以不至于太快的传入到下一级同步元件中,这个说的就是hold time.接下来为了保证数据可以在不同的数据流之间进行转换,也就是说由A发出的数据能够正确的被B所采集,以此类推,保证了数据在所有的同步元件中正常传输,为了达到这个目的,就要求发出的数据满足采集数据同步元件的setup time. 依照上面的论述,要使得同步电路正常的工作,首先要保证数据能够

深入理解HTTP协议(转)原出处已不明

http协议学习系列---我从这里转来的http://www.blogjava.net/zjusuyong/articles/304788.html 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC

从多级延迟触发器到边沿检测

一.多级延迟触发器(或延迟触发器链) (1)多级延迟触发器电路 多级延迟触发器,顾明思议就是多个触发器串在一起,对信号进行打拍,一个触发器就延时了一拍,也就是延迟了一个时钟周期. 多级触发器的代码如下所示:  1 module DFF_N #(parameter N=3)(  2   input clk,  3   input reset,  4   input [N-1:0] D,  5   output reg [N-1:0] Q  6 );  7 reg [N-1:0]d0;  8 reg