AngularJs $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
AngularJs $q 承诺与延迟的更多相关文章
- Angular - - $q 承诺与延迟
$q 一个帮助处理异步执行函数的服务.当他们做完处理时,使用它们的返回值(或异常). 受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用. $q的两种方式- ...
- angular的$q,defer,promise
$q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常). 官网:http://docs.angularjs.cn/api/ng/servi ...
- angularjs 缓存 $q
<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...
- 深入浅出HTTP协议(WEB开发和面试必备)
1. 基础概念篇 a.简介 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...
- 深入理解http/https协议
深入理解HTTP协议(转) http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(Wo ...
- 转载和积累系列 - 深入理解HTTP协议
深入理解HTTP协议 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...
- Linux常用命令(三)
1.top 说明:即时显示 process 的动态 语法格式:top [-] [d delay] [q] [c] [S] [s] [i] [n] [b]基本参数:d : 改变显示的更新速度,或是在交谈 ...
- http协议学习系列
深入理解HTTP协议(转) http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列 1. 基础概念篇 1.1 介绍 H ...
- 深入理解HTTP协议、HTTP协议原理分析【转】
转自:http://blog.csdn.net/lmh12506/article/details/7794512 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 基础概念篇 ...
随机推荐
- 软件工程(DBSD2016) Git Review
说明:任何问题请在评论区说明,会集中更新回复. 连连看组 源码: git clone https://git.coding.net/jx8zjs/llk.git 提交日志 一共有20次commit日志 ...
- 本地的html怎么直接通过路径就读取本地文件。
我要做的事情是已知一个目录的相对路径,获得这个路径下面所有的txt文件,然后读到一个JS Script里面做下一步处理. 网上的例子都是使用input的,既然我是local的html文件,也知道路径了 ...
- opencv8-GPU之相似性计算
Opencv支持GPU计算,并且包含成一个gpu类用来方便调用,所以不需要去加上什么__global__什么的很方便,不过同时这个类还是有不足的,待opencv小组的更新和完善. 这里先介绍在之前的& ...
- 【干货分享】JPager.Net MVC超好用轻量级分页控件
JPager.Net MVC好用的轻量级分页控件,好用到你无法想象,轻量到你无法想象. JPager.Net MVC好用的轻量级分页控件,实现非常简单,使用也非常简单. JPager.Net M ...
- APP架子迁移指南(二)
接上一篇,这一篇开始用android来解释MVP概念.八股式的架子结构和命名规范.我在准备这篇文章的时候还看到不少在MVP基础上衍生的架子思路,底子是MVP没错,但命名有区别.复杂度变了.架子也用到了 ...
- 《深入理解Spark:核心思想与源码分析》(前言及第1章)
自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...
- operating expense & captial expenditure
营运成本(营业成本, operating expense, OPEX) 指的是运行企业的持续性.消耗性的支出,与之对照的是资本支出(captial expenditure, CAPEX).例如:购买影 ...
- matlab 中randn randi rand randsrc的用法以及区别
1,rand 生成均匀分布的伪随机数.分布在(0~1)之间 主要语法:rand(m,n)生成m行n列的均匀分布的伪随机数 rand(m,n,'double') ...
- iOS--更新cooped库
- C# 对sharepoint 列表的一些基本操作,包括添加/删除/查询/上传文件给sharepoint list添加数据
转载:http://www.cnblogs.com/kivenhou/archive/2013/02/22/2921954.html 操作List前请设置SPWeb的allowUnsafeUpdate ...