前言:前端发送请求时我们经常用trycatch来捕获错误信息,但是你会不会觉得有时代码因为trycatch而导致嵌套太多大括号了呢?这些括号让我们的代码看起来眼花缭乱,下面我们就来优化trycatch,让我们的代码看起来整整齐齐把!
在此之前,我们要先储备一些关于Promise对象的基础知识.话不多说,上代码!来喽来喽~~
一、如何拿到Promise对象请求成功的结果
1.封装一个函数,函数中返回Promise对象,方便复用这段代码
// 封装一个函数,函数中返回Promise对象
function MyPromise (){
return new Promise((resolve, reject) => {
setTimeout(() => { //设置一个定时器模拟发起请求的过程
//假设2秒后请求成功,rsolve()方法会触发promise对象的then方法,
//因此,成功的结果会在then()中打印
resolve('请求成功啦,数据回来啦!')
}, 2000)
})
}
2.开始调用方法,模拟请求成功的过程
2.1调用代码逻辑
2.1.1知识点提炼
-
Promise对象成功的结果会返回到它的then方法中,失败的结果会返回在它的catch方法中
-
Promise对象中的rsolve()方法会触当前这个promise对象的then方法执行
-
Promise对象中的reject()方法会触发当前这个promise对象的catch方法执行
const pA = MyPromise() //定义变量pA接收函数调用时返回的Promise对象
// 知识点:Promise对象成功的结果会返回到它的then方法中,失败的结果会返回在它的catch方法中
// 使用pA.then().catch()接收返回的成功/失败的结果
//问题:为什么定义pB,因为Promise的.then方法会在原地返回一个全新的Promise对象,刚好下面需要用这个Promse对象,所以就定义变量接收啦
const pB = pA.then(res=>{
//打印成功的结果
console.log(res) //效果:2秒后 打印 "请求成功啦,数据回来啦!"
}).catch(err=>{
console.error(err)//打印失败的结果
})
2.2效果
聪明的你肯定猜到了吧?控制台打印出了 "请求成功啦,数据回来啦!" 这句话.对啦!因为resolve()触发了promise对象pA的then方法?那思考一下,请求失败的错误信息在哪里可以拿到呢?
二、如何拿到Promise对象请求失败的结果
1.再次调用方法,模拟请求失败的过程
1.1修改一下封装的函数MyPromise
function MyPromise (){
return new Promise((resolve, reject) => {
setTimeout(() => { //设置一个定时器模拟发起请求的过程
//假设2秒后请求失败,reject()方法会触发promise对象的catch方法,
// 因此,成功的结果会在catch()中打印
reject('请求失败啦,臭宝~~')
}, 2000)
})
}
1.2获取请求失败的结果
const pA = MyPromise() //定义变量pA接收函数调用时返回的Promise对象
// 知识点:Promise对象成功的结果会返回到它的then方法中,失败的结果会返回在它的catch方法中
// 使用pA.then().catch()接收返回的成功/失败的结果
//问题:为什么定义pB,因为Promise的.then方法会在原地返回一个全新的Promise对象,刚好下面需要用这个Promse对象,所以就定义变量接收啦
const pB = pA.then(res=>{
//打印成功的结果
console.log(res)
}).catch(err=>{
//打印失败的结果
console.error(err)//效果:2秒后 打印 "请求失败啦,臭宝~~"
})
1.3效果
三、 promise对象then中return 一个值会是什么效果
1.加个return语句试一试
const pA = MyPromise() //定义变量pA接收函数调用时返回的Promise对象
const pB = pA.then(res=>{
//打印成功的结果
console.log(res)
return 666 // 666 会在哪里打印呢
}).catch(err=>{
console.error(err)//打印失败的结果
})
console.log(pB) //选择A:这里打印666
pB.then(res=>{
console.log(res) //选择B:这里打印666
})
我已经听到你在说B答案啦~对啦,原因是什么呢?
答:promise对象的then()方法执行完默认会在原地返回一个全新的Promise对象,
但是,如果你在then方法中return 一个非Promise对象,那么这个return 的值就会在这个全新的Promise对象的then方法中使用。
如果return 一个Promise对象,那么这个return 的Promise对象就替代默认被返回留在原地的那个Promise对象。
2.控制台效果
5.思考?promise对象catch中return 一个值会在哪里出现
这一部分的结论:是我们优化trycatch的关键原理!!!!
是不是下意识觉得会出现在他自己catch方法中?实际上并不是哦!
5.1试一试
<script>
// 封装一个函数,函数中返回Promise对象
function MyPromise (){
return new Promise((resolve, reject) => {
setTimeout(() => { //设置一个定时器模拟发起请求的过程
reject('请求失败啦,臭宝~~') //这里要改成reject
}, 2000)
})
}
const pA = MyPromise()
const pB = pA.then(res=>{
console.log(res) //打印成功的结果
return 666
}).catch(err=>{
console.error(err)//打印失败的结果->'请求失败啦,臭宝~'
return 886
})
console.log(pB) //打印结果是Promise对象,是pA.then()在原地返回的
pB.then(res=>{
console.log(res)
}).catch(err=>{
console.error(err)
})
</script>
5.2效果:
总结:在promise对象的catch方法中return的非promise对象(例如数值)也会在它原地返回的那个全新Promise对象的then方法中使用
6.思考:如何区分接收的数据是成功结果还是失败结果?
经过上面我们已经知道啦,promise的then方法中可以通过借助一个新的Promise对象就拿到成功失败的结果?现在我们的重点是如何区分是成功结果还是失败结果
提示:在return的时候就给这个结果一个标识,让我们知道他的底细
6.1 5、4、3、2、1~上代码!!
//-----------------------1---------------
// 封装一个函数,函数中返回Promise对象
function MyPromise (){
return new Promise((resolve, reject) => {
setTimeout(() => { //设置一个定时器模拟发起请求的过程
reject('请求失败啦,臭宝~~')
}, 2000)
})
}
//--------------------2----------------------------
const pA = MyPromise() //定义变量pA接收函数调用时返回的Promise对象
const pB = pA.then(res=>{
//打印成功的结果
console.log(res)
return [null,'{success:"成功结果"}']
}).catch(err=>{
console.error(err)//打印失败的结果
return ['失败结果',null]
})
console.log(pB)
//----------------3--------------------------
pB.then(res=>{
//数组的结构赋值
let [err,success] =res
// 有错误对象,说明Promise内部报错了
if(err) console.error(err)
//否则,请求成功
else console.log(success)
}).catch(err=>{
})
6.2效果展示
现在你已经学会如何在promise的then方法中同时拿到成功结果失败结果.是不是有了优化trycatch的灵感?
提示:把第三段代码想成逻辑页面的await,然后用then和catch来提取axios的Promise对象成功或失败结果.
注意:在promise的then方法中同时拿到成功结果失败结果的前提是,要使用一个全新的Promise对象来中转,这真是将偷梁换柱移花接木展现的淋漓尽致!!
具体优化看这里:CSDN