JavaScript中的Promise对象
传统的异步编程解决方案是使用回调函数和事件,Promise是异步编程的一种解决方案
从语法上来讲,Promise是一个对象,从它可以获取异步操作的消息
ECMAscript6原生提供了Promise对象,在这之前,想要使用Promise,一般会借助于第三方库
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
此外,Promise对象提供统一的API接口,各种异步操作都可以用同样的方法进行处理,更加方便简单
Promise对象有三种状态
pending:进行中,MDN文档中称为待定
resolved/fulfilled:已完成,MDN文档中称为已兑现
rejected:已失败,MDN文档中称为已拒绝
resolved和fulfilled都表示已完成的状态,两者完全相同
Promise对象的特点
无法取消,一旦新建它就会立即执行,无法中途取消
当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
状态一旦改变,就不会再变,无法再次改变状态
无论成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的一般称为reason或error
如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
Promise实例对象的创建
使用new关键字来调用Promise的构造器来进行实例化从而创建一个promise对象:
var promise = new Promise(function(resolve, reject) {
处理语句
resolve("成功!");
reject("失败");
});
Promise构造函数需要传入一个函数作为回调
传入的函数有两个参数(参数为函数)
调用第一个函数可以返回resolved状态,调用时传入的值作为value
调用第二个函数可以返回rejected状态,调用时传入的值作为reason
p = new Promise((a,b)=>a('ok')); //返回值为ok
抛出异常也会导致变为rejected状态,且返回值为抛出的异常
Promise.resolve(val):快速的获取一个状态为resolved的Promise对象
当val为Promise对象时,状态和返回值都由val决定,不一定为resolved
当val非Promise对象时,状态为resolved,val为返回值
Promise.reject(val):快速的获取一个状态为rejected的Promise对象
状态为rejected,无论val是不是Promise对象,都作为reason返回
Promise.resolve()和Promise.reject()方法就是一个用来快速得到Promise对象的语法糖
Promise.all(iterable)
iterable:一个可迭代对象,依次获取元素的状态和返回值
如果元素非Promise对象,则使用Promise.resolve()转换该元素
返回一个新的promise
所有元素状态都为resolved返回resolved状态,返回值为所有元素的返回值组成的数组
只要有一个元素状态为rejected,那么终止遍历立即返回rejected状态,返回值为该元素的返回值
Promise.allSettled(iterable)
iterable:一个可迭代对象,依次获取元素的状态和返回值
如果元素非Promise对象,则使用Promise.resolve()转换该元素
返回一个新的resolve状态的promise,返回值为所有元素和状态和返回值组成的数组
返回值数组中每个元素为一个对象,status属性表示该元素的状态
如果状态为resolved,那么属性value为返回值
如果状态为rejected,那么属性reason为返回值
Promise.any(iterable):当任意一个元素状态变为resolved,就返回这个元素的状态和返回值
Promise.race(iterable):当任意一个元素状态改变时(无论成功还是失败),就返回这个元素的状态和返回值
then()方法
then()方法表示等待promise对象的状态由pending发生了改变就立即执行,then()方法包含两个参数方法,分别是resolved的回调和rejected的回调,如:
p = new Promise(
function(resolve,reject){
setTimeout(function (){resolve('success');},5000);
}
);
p.then(function(value){console.log(value);});
//5秒控制台会显示'success'
由于then()本身会返回一个新的promise,所以后一个then()针对的永远是一个新的promise,可以链式调用
catch()方法
catch()方法的作用是捕获Promise的错误,与then()的第二个参数rejected回调作用几乎一致
由于Promise的抛错具有冒泡性质,能够不断向后传递,所以建议不使用then()的rejected回调来处理错误,而是在整个链式最后使用一个catch()统一处理这些错误
done()方法
用法类似于then(),可以提供resolved和rejected两个回调参数,也可以不提供任何参数,主要作用是在回调链的尾端捕捉前面没有被捕捉到的错误
finally()方法
接受一个函数作为参数,这个函数不管promise最终的状态是怎样,都一定会被执行
有些时候不管成功与否,一些资源都需要释放,那么我们需要在最后的then()和最后的catch()中书写两遍完全相同的资源释放处理语句
这时候如果在最后使用finally()就可以仅书写一遍就达到目的