ES6新增特性——Promise
一:为什么会出现?
1、场景一:在很多业务需求中,你需要通过ajax进行多次请求,而且每次请求返回的数据需要作为参数进行下一次的请求,于是会出现ajax层层嵌套问题。多个请求操作层层依赖,加上每一层还会有复杂的业务逻辑需要处理,使得代码可读性很差,不直观,难以维护和调试。
注:这种回调函数层层嵌套又称为回调地狱
//请求A $.ajax({ success:function (res1) { //请求B $.ajax({ success:function (res2) { //请求C $.ajax({ success:function (res3) { ...... ....... } }) } }) } })
2、场景二:如果请求C依赖于请求A和B的结果,但A和B之间互不依赖,如果仍写成A嵌套B,B嵌套C的形式,无疑是会消耗更多的等待时间。
故出现Promise对象来更合理和规范地处理异步操作。JS中所有代码都是单线程执行,如果必须是异步执行,可以通过回调函数实现
二:如何使用?
Promise对象是全局对象,可以理解为一个类。
Promise对象有三种状态:
pending:刚创建实例,表示初始化状态
fulfilled:resolve方法调用的时候,表示操作成功
rejected:reject方法调用的时候,表示操作失败
1、通过new生成一个实例,参数是一个匿名函数,其中有两个参数resolve,reject
var pro = new Promise(function (resolve, reject) {
//pending状态 if ('操作成功') { resolve();//resolve:处理异步操作执行成功后的回调函数 fulfiied状态 } else { reject();//reject:处理异步操作失败后的回调函数 rejected状态 } })
2、then()方法:用于处理操作后的处理程序
pro.then(function (res) { //执行resolve回调函数 }, function (error) { //执行reject回调函数 })
3、catch()方法:处理操作异常的程序
pro.catch(function (error) { //执行reject回调函数 })
综合上面两个方法,一般用then方法处理操作成功的程序,catch用来处理操作异常的程序
pro.then(function (res) { //执行resolve回调函数 }).catch(function (error) { //执行reject回调函数 })
完整示例:最后输出结果为:执行成功
var pro = new Promise(function (resolve, reject) { //pending状态 if (true) { resolve('执行成功');//resolve:处理异步操作执行成功后的回调函数 fulfiied状态 } else { reject('执行失败');//reject:处理异步操作失败后的回调函数 rejected状态 } }) pro.then(function (res) { //执行resolve回调函数 console.log(res) }).catch(function (error) { //执行reject回调函数 console.log(error) })
三:如何解决回调地狱问题?
var pro = new Promise(function (resolve, reject) { if (true) { resolve('执行成功'); } else { reject('执行失败'); } }) pro.then(A) .then(B) .then(C) .catch(D) function A(res) { console.log(res) //执行成功 return '给下一个B请求传参:成功执行A'; } function B(res) { console.log(res) //给下一个B请求传参:成功执行A return '给下一个C请求传参:成功执行B'; } function C(res) { console.log(res) //给下一个C请求传参:成功执行B } function D(error) { console.log(error) }
可以通过多个then方法进行链式操作,通过return方式给下一个执行回调函数传参,如上示例的结果是
执行成功
给下一个B请求传参:成功执行A
给下一个C请求传参:成功执行B
四:如何解决场景二问题?
Promise.all()方法:当参数中的实例对象的状态都为fulfilled时,Promise.all()才会执行resolve函数
var pro1 = new Promise(function (resolve, reject) { setTimeout(resolve('成功执行1'),5000); }); var pro2 = new Promise(function (resolve, reject) { setTimeout(resolve('成功执行2'),1000); }); Promise.all([pro1,pro2]).then(function (res) { console.log(res) })
pro1在1000ms以后成功进入fulfilled状态,但此时Promise.all还是不会有行动,需要等到pro2进入到fulfilled状态时,才会进入then方法,故5000ms以后执行结果为:
[
'成功执行1',
'成功执行2'
]
类似的方法还有Promise.race()方法,参数为Promise实例,只要有一个状态发生改变,不管是成功fulfiied还是失败rejected状态,就会有返回,其他实例再有变化也不会再处理了。
var pro1 = new Promise(function (resolve, reject) { setTimeout(resolve,5000,'成功执行1'); }); var pro2 = new Promise(function (resolve, reject) { setTimeout(reject,1000,'失败执行2'); }); Promise.race([pro1,pro2]).then(function (res) { console.log(res) }).catch(function (error) { console.log(error) })
执行结果为:
失败执行2