什么是Promise?
Promise是ES6异步编程的一种解决方案(目前最先进的解决方案是async和await的搭配(ES8),但是它们是基于promise的),从语法上讲,Promise是一个对象或者说是构造函数,用来封装异步操作并可以获取其成功或失败的结果。
Promise的使用场景和好处
使用场景
Promise通常被用于Ajax请求中,由于网络设备的不同,请求得到的返回值事件也不同,但是执行下一步的代码的同时又需要上一步请求得到的返回值,这时候就需要等待请求到返回值,才知道下面的程序如何进行,在这种情况下通常使用Promise解决。
使用Promise的优缺点
- 优点
- 可以避免多层异步代码调用嵌套问题,即解决回调地狱;
- 使用
Promise提供了更加简单的API用来操作异步。
- 缺点
- 无法取消
Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
Promise的三种状态
pending:等待中或者进行中,表示还没有结果;
2.
resolved(Fulfilled):成功状态,表示已经完成,可以继续往下进行;
3.
rejected:失败状态:结果错误,拒绝继续往下执行;
这三种状态不受外界影响,而且状态只能从
pending改变为resolved或者rejected,并且不可逆。
Promise的语法
const p = new Promise((resolve,reject)=>{
//书写异步代码
//异步成功:调用resolve('Promise状态成功'),向外传出,代码执行then()里的函数题并传参数;
//异步失败:调用reject('Promise状态异常'),向外传出,代码执行catch()里的函数体并传参数;
})
p.then((res)=>{
//用来接收异步成功的结果
console.log(res)
}).catch((err)=>{
//用来接收异步失败的结果
console.error(err)
})
Promise的特点
- 在Promise对象的构造函数中,将一个
函数作为第一个参数; - 而Promise对象的构造函数的第一个参数中的这个函数,就是用来处理Promise的状态变化,这个函数的第一个参数
resolved表示promise的状态为成功,第二个参数rejected表示promise的状态为失败,这两个参数名(可以自定义)都作为一个函数,他们的作用分别是将promise状态修改为成功和失败; - Promise对象中的
then方法,可以接收构造函数中处理的状态变化,并分别对应执行。then方法有2个函数参数,第一个函数接收resolved(promise状态为成功)的执行,第二个函数接收reject(promise状态为失败)的执行; - promise的状态只能从
未完成->完成(pending->fulfilled),未完成->失败(pending->rejected)且状态不可逆转。
Promise解决回调地狱
Promise链式调用法
let result = axios({url: 'http://123.57.109.30:3999/api/categoryfirst'}).then(res => {
return axios({url: `http://123.57.109.30:3999/api/categorySecond?firstId=${res.data.list[8].firstId}`})
}).then(res => {
return axios({url: `http://123.57.109.30:3999/api/categoryThird?secondId=${res.data.list[0].secondId}`})
}).then(res => {
return axios({url: `http://123.57.109.30:3999/api/goodsList?thirdId=${res.data.list[0].thiredId}`})
}).then(res => {
console.log(res.data);
})
响应结果
ES8解决回调地狱法
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js"></script>
<script>
const fn = async () => {
const res = await axios({url: 'http://123.57.109.30:3999/api/categoryfirst'})
const res2 = await axios({url: `http://123.57.109.30:3999/api/categorySecond?firstId=${res.data.list[8].firstId}`})
const res3 = await axios({url: `http://123.57.109.30:3999/api/categoryThird?secondId=${res2.data.list[0].secondId}`})
const res4 = await axios({url: `http://123.57.109.30:3999/api/goodsList?thirdId=${res3.data.list[0].thiredId}`})
console.log(res4.data);
}
fn()
</script>
响应结果