目录
一、promise是什么?
Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
1.promise对象
1、Promise对象是一个为异步操作提供统一API,以供异步操作进一步处理的对象。
2、Promise对象的两个特点:
① 对象的状态不受外界影响
有三种状态:Pending(进行中)、Resolved(已完成)、Rejected(已失败)
只有异步操作的结果可以决定当前是哪一种状态
② 一旦状态改变,就不会再变,任何时候都可以得到这个结果
3、Promise对象的缺点:
① 无法取消 Promise,一旦新建它就会立即执行,无法中途取消
② 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部
③ 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
2.Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
3.先new一个promise小案例
调用resolve()方法可以将promise对象转成成功状态
调用reject()方法可以将promise对象转成失败状态
promise对象,提供了两个方法:
A. then(回调函数) -> 获取promise成功的状态结果
B. catch(回调函数) -> 捕获promise失败的状态结果
function p1(){
return new Promise((resolve) => {
setTimeout(() => {
console.log(执行完成);
resolve({a:1,b:2})
},1000)
})
}
p1().then((res) => {
})
其执行过程是:执行了一个异步操作,也就是setTimeout,1秒后,输出“执行完成”,并且调用resolve方法。
reject方法
reject就是失败的时候的回调,他把promise的状态修改为reject,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。
function getUserInfo(username){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:username
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
function getGoodsInfo(userId){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:userId
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
function getGoodsInfo(goodsId){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/goodsinfo',
method:'post',
data:{
id:goodsId
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
getUserInfo('a123123').then((res) => {
return getOrderInfo(res.info.user_id)
}).then((res) => {
return getGoodsInfo(res.info.goods_id)
}).then((res) => {
console.log('成功',res);
}).catch((err) => {
console.log('失败',err);
}).finally(() => {
console.log('都会执行');
})
catch方法
与Promise对象方法then方法并行的一个方法就是catch,与try catch类似,catch就是用来捕获异常的,也就是和then方法中接受的第二参数rejected的回调是一样的
function getUserInfo(username){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:username
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
function getGoodsInfo(userId){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:userId
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
function getGoodsInfo(goodsId){
return new Promise((reslove,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/goodsinfo',
method:'post',
data:{
id:goodsId
},
success:function(res){
reslove(res)
},
error:function(err){
reject(err)
}
})
})
}
getUserInfo('a123123').then((res) => {
return getOrderInfo(res.info.user_id)
}).then((res) => {
return getGoodsInfo(res.info.goods_id)
}).then((res) => {
console.log('成功',res);
}).catch((err) => {
console.log('失败',err);
}).finally(() => {
console.log('都会执行');
})
Promise.all() 方法
与then同级的另一个方法,all方法,该方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后并且执行结果都是成功的时候才执行回调。
function getUserInfo(username){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:username
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
}).catch((err) => {
return 'getUserInfo错误';
})
}
function getOrderInfo(userId){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:userId
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
}).catch((err) => {
return 'getOrderInfo错误';
})
}
function getGoodsInfo(goodsId){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/goodsinfo',
method:'post',
data:{
id:goodsId
},
success:function(res){
reject(res)
},
error:function(err){
reject(err)
}
})
}).catch((err) => {
return 'getGoodsInfo错误';
})
}
Promise.all([getUserInfo('a123123'),getOrderInfo(1),getGoodsInfo('1,2,3')]).then((res) => {
console.log(res)
}).catch((err) => {
console.log('失败',err)
})
执行特点:
只有三个promise实例的状态都确定为成功时,Promise.all的最终状态才是成功;
只要有一个出现错误,Promise.all()的状态就会变成失败。
如何避免一个错,Promise.all最终变成错误状态这个问题:
给每个请求实例写上单独的catch!
Promise.race() 方法
all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
同时执行多个实例,哪个先确定状态,race方法就以哪个状态为主
function p1(){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('p1');
},4000)
})
}
function p2(){
return new Promise((resolve,reject) => {
setTimeout(() => {
reject('p2');
},2000)
})
}
function p3(){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('p3');
},3000)
})
}
Promise.race([p1(),p2(),p3()]).then((res) => {
console.log('成功',res)
}).catch((error) => {
console.log('失败',error)
});
Promise.allSettled(看实例就好)
并发去执行多个实例,但是,就算有实例失败,也会进入到allSettled的成功方法中去(then)
function getUserInfo(username){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:username
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
})
}
function getOrderInfo(userId){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:userId
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
})
}
function getGoodsInfo(goodsId){
return new Promise((resolve,reject) => {
$.ajax({
url:'http://www.web14ban.com/index.php/index/goods/goodsinfo',
method:'post',
data:{
id:goodsId
},
success:function(res){
reject(res)
},
error:function(err){
reject(err)
}
})
})
}
//
Promise.allSettled([getUserInfo('a123123'), getOrderInfo(1), getGoodsInfo('1,2,3')]).then((res) => {
console.log('成功',res)
}).catch((err) => {
console.log('失败',err)
})