angularjs promise详解
一、什么是Promise
Promise是对象,代表了一个函数最终可能的返回值或抛出的异常,就是用来异步处理值的。
Promise是一个构造函数,自己身上有all、reject、resolve这几个异步方式处理值的方法,原型上有then、catch等同样很眼熟的方法。
二、为什么使用Promise
有了Promise
对象,就可以把异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise
对象提供了统一的接口,使得控制异步操作更加容易。
Promise
对象有以下2个特点:
1.对象的状态不受外界影响。
Promise
对象代表一个异步操作,有三种状态:Pending(进行中)
、Resolved(已完成)
和Rejected(已失败)
。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2.一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise
对象的状态改变,只有两种可能:从Pending
变为Resolved
;从Pending
变为Rejected
。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
三、如何创建一个Promise
先贴一段代码:
define([
'angularModule'
],function (app) {
app.register.service('httpRequestService', ['$http', '$q', function ($http, $q) {
return{
request: function (params) {
var deferred = $q.defer();
$http({
method : params.method,
url : params.url
}).success(
function (data) {
deferred.resolve(data);
}
).error(
function(data){
deferred.reject(data);
}
);
return deferred.promise;
}
}
}])
});
讲一下$q服务
q服务是AngularJS中自己封装实现的一种Promise实现。
要创建一个deferred对象,可以调用defer()方法:
var deferred = $q.defer(); //deffered上面暴露了三个方法,以及一个可以用于处理promise的promise属性。 //promise属性里面又包含了then、catch、finally三个方法
在Promise中,定义了三种状态:等待状态,完成状态,拒绝状态。
deffered API
1.deffered 对象的方法
1.resolve(value):在声明resolve()处,表明promise对象由pending状态转变为resolve。
2.reject(reason):在声明resolve()处,表明promise对象由pending状态转变为rejected。
3.notify(value)
:在声明notify()处,表明promise对象unfulfilled状态,在resolve或reject之前可以被多次调用。
2.deffered 对象属性
promise :最后返回的是一个新的deferred对象 promise 属性,而不是原来的deferred对象。这个新的Promise对象只能观察原来Promise对象的状态,而无法修改deferred对象的内在状态可以防止任务状态被外部修改。
3.Promise API
当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过 deferred.promise 得到该引用。
promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。
4.promise 对象的方法
1.then(errorHandler, fulfilledHandler, progressHandler):then方法用来监听一个Promise的不同状态。errorHandler监听failed状态,fulfilledHandler监听fulfilled状态,progressHandler监听unfulfilled(未完成)状态。此外,notify 回调可能被调用 0到多次,提供一个进度指示在解决或拒绝(resolve和rejected)之前。
2.catch(errorCallback) ——
promise.then(null, errorCallback) 的快捷方式
3.finally(callback) ——让你可以观察到一个
promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise
被拒绝还是解决。
q常用的几个方法:
- defer() 创建一个deferred对象,这个对象可以执行几个常用的方法,比如resolve,reject,notify等
- all() 传入Promise的数组,批量执行,返回一个promise对象
- when() 传入一个不确定的参数,如果符合Promise标准,就返回一个promise对象。
all()方法
当批量的执行某些方法时,就可以使用这个方法。有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。
用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。
那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是 下面的results。所以下面代码的输出结果就是:
var funcA = function(){
console.log("funcA");
return "hello,funA";
}
var funcB = function(){
console.log("funcB");
return "hello,funB";
}
$q.all([funcA(),funcB()])
.then(function(result){
console.log(result);
});
执行的结果:
funcA
funcB
Array [ "hello,funA", "hello,funB" ]
when()方法
when方法中可以传入一个参数,这个参数可能是一个值,可能是一个符合promise标准的外部对象。
var funcA = function(){
console.log("funcA");
return "hello,funA";
}
$q.when(funcA())
.then(function(result){
console.log(result);
});
当传入的参数不确定时,可以使用这个方法。
hello,funA
四、链式请求
通过then()方法可以实现promise链式调用,因为then方法总是返回一个新的promise。
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
});
function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
}
运行结果:
angularjs promise详解的更多相关文章
- angular $q promise详解
前言 通过本文,你大概能清楚angular promise是个啥,$q又是个啥,以及怎么用它.这里咱们先灌输下promise的思想. 下面写的全是废话,一些看着高逼格其实没什么大作用的概念,想知道$q ...
- angularjs 指令详解 - template, restrict, replace
通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统. 怎样定义自己的指令呢? 我们通过 Bootstrap UI来学习吧.这个项目使用 angula ...
- AngularJS Providers 详解
供应者(Providers) Each web application you build is composed of objects that collaborate to get stuff d ...
- AngularJS开发指南5:AngularJS表达式详解
AngularJS表达式类似Javascript的代码片段,通常在数据绑定中用到,写在双大括号中,如:{{表达式}}.表达式是用$parse方法来处理的. 下面是一些合法的AngularJS表达式 1 ...
- angularJS directive详解
前言 最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方. Angularjs指令定义的API AngularJs的指令定义大致如下 angul ...
- angularjs filter 详解
系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter.如果对smarty比较熟悉的话,学习angularjs会比较容易一点.这 ...
- angularJS directive详解(自定义指令)
Angularjs指令定义的API AngularJs的指令定义大致如下 其中return返回的对象包含很多参数,下面一一说明 1.restrict (字符串)可选参数,指明指令在DOM里面以什么形式 ...
- ES6 中 Promise 详解
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Promise 提供统一的 API ...
- ES6中Promise详解
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息. Promise 提供统一的 AP ...
随机推荐
- 我不知道的行高——line-height
概述 对于块级元素,CSS属性line-height指定了元素内部line-boxes的最小高度. 对于非替代行内元素,line-height用于计算line box的高度. 对于替代行内元素,如bu ...
- CSS 圣杯布局升级版---多个固定宽度一个自适应宽度
1.一个div固定,一个div自适应宽度.两种情况,固定在左或者在右. HTML: <div class="box1"> <div class="mai ...
- LNMP搭建环境遇到的N多坑
最近配置开发用的lnmp环境,环境配置完成后,爆500错误,查看nginx错误日志 open_basedir 将 PHP 所能打开的文件限制在指定的目录树,包括文件本身 错误日志显示,访问脚本不在 o ...
- CentOs下 SVN版本控制的安装(包括yum与非yum)
一.yum安装 rpm -qa subversion //检查是否安装了低版本的SVN yum remove subversion //如果存储旧版本,卸载旧版本SVN 开始安装 yum -y ins ...
- Mysql基准测试详细解说(根据慕课网:《打造扛得住Mysql数据库架构》视频课程实时笔录)
什么是基准测试 基准测试是一种测量和评估软件性能指标的活动用于建立某个时刻的性能基准,以便当系统发生软硬件变化时重新进行基准测试以及评估变化对性能的影响. 我们可以这样认为:基准测试是针对系统设置的一 ...
- Asp.Net Core Identity+EFCore + Mysql踩坑记录
搭建基础框架准备试试传说中的Identity,本以为很顺利,结果一路踩了N多坑 遂就把过程记录下来.方便自己以后查看,也希望能帮到遇到同样问题的朋友. 1.首先,引入Identity需要的类库,还有M ...
- Java集合框架(一)—— Collection、Iterator和Foreach的用法
1.Java集合概述 在编程中,常常需要集中存放多个数据.当然我们可以使用数组来保存多个对象.但数组长度不可变化,一旦在初始化时指定了数组长度,则这个数组长度是不可变的,如果需要保存个数变化的数据,数 ...
- 深度学习中batch normalization
目录 1 Batch Normalization笔记 1.1 引包 1.2 构建模型: 1.3 构建训练函数 1.4 结论 Batch Normalization笔记 我们将会用MNIST数 ...
- IntentService源码
原文地址IntentService源码分析 @Override public void onCreate() { super.onCreate(); HandlerThread thread = ne ...
- nyoj28 大数阶乘 亿进制优化
思路:刚开始用的十进制模拟手算加法,超时了.然后想到刘汝佳大哥书上面用的亿进制能够加速大数运算,果然180ms过掉了. 亿进制与十进制相同,只不过是把八位看做一位,例如6464654654165,看成 ...