$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

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

  1. AngularJs $q 承诺与延迟

    $q 一个帮助处理异步执行函数的服务.当他们做完处理时,使用它们的返回值(或异常). 受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用. $q的两种方式- ...

  2. angular的$q,defer,promise

    $q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常). 官网:http://docs.angularjs.cn/api/ng/servi ...

  3. angularjs 缓存 $q

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  4. 深入浅出HTTP协议(WEB开发和面试必备)

    1. 基础概念篇   a.简介 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...

  5. 深入理解http/https协议

    深入理解HTTP协议(转) http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(Wo ...

  6. 转载和积累系列 - 深入理解HTTP协议

    深入理解HTTP协议 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...

  7. Linux常用命令(三)

    1.top 说明:即时显示 process 的动态 语法格式:top [-] [d delay] [q] [c] [S] [s] [i] [n] [b]基本参数:d : 改变显示的更新速度,或是在交谈 ...

  8. http协议学习系列

    深入理解HTTP协议(转)  http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列   1. 基础概念篇 1.1 介绍 H ...

  9. 深入理解HTTP协议、HTTP协议原理分析【转】

    转自:http://blog.csdn.net/lmh12506/article/details/7794512 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 基础概念篇 ...

随机推荐

  1. C#入门经典第11章集合-1

  2. 关于Tcpreplay

    tcpprep -p -o /root/Desktop/ZS/Tcpreplay/cache_test.cache -i /root/Desktop/ZS/Tcpreplay/9.17.pcap tc ...

  3. git@osc使用教程

    http://my.oschina.net/openswc/blog/142321 Git初体验 http://my.oschina.net/dxqr/blog/134811 网友整理的git@osc ...

  4. ubuntux下apk反编译工具安装

    1,下载dex2jar工具.(http://download.csdn.net/detail/u013647453/8286693) 2,下载jd-gui工具(http://jd.benow.ca/) ...

  5. CodeForces 598E Chocolate Bar

    区间DP预处理. dp[i][j][k]表示大小为i*j的巧克力块,切出k块的最小代价. #include<cstdio> #include<cstring> #include ...

  6. Linux下hosts、host.conf、resolv.conf

    /etc/resolv.conf 该文件是DNS域名解析的配置文件,它的格式很简单,每行以一个关键字开头,后接配置参数. resolv.conf的关键字主要有四个,分别是: nameserver   ...

  7. AngularJs ng-class 使用

    今天在做项目的时候要对表格内的部分的最大最小值高亮 解决方案 1. 引用 ng-class 2. 引用原型求最大最小值 实例 AngularJs HTML 代码 <table class=&qu ...

  8. iOS HTTP不能正常使用

  9. bzoj4010: [HNOI2015]菜肴制作【拓扑排序】

    想到了一个分治方法,每一次尽量放小的那个,把它依赖的放在左边,不依赖的放在右边. TLE 80: #include <bits/stdc++.h> #define rep(i, a, b) ...

  10. 打包程序时的证书问题(上传APP就出现Missing iOS Distribution signing indetity for)

    现象: 解决办法: 1.删除本地钥匙串中的这个文件,注意“系统”中的同名文件也必须删除 2.进入http://www.apple.com/certificateauthority/ 下载新的(WWDR ...