在项目中,我们经常会遇到这样的需求:第二个接口请求的参数必须要等到第一个接口返回值回来,才能去请求第二个接口。也就是说:第二个函数的参数是第一个函数的返回值!
通常遇到这种情况,我们都会想到使用
Promise
去处理这样的异步需求。因为之前知道除Promise
外还有async/await
,但是一直没有研究过,今天就来研究一下!async基础知识参考链接:juejin.cn/post/684490…
一篇关于promise以及async对比的比较通俗简洁的文章:juejin.cn/post/684490…
解决async地狱:juejin.cn/post/684490…
1. 关于async/await的重要点汇总:
- 首先,async 永远会返回一个promise函数!
- async函数返回的promise,必须等到内部所有的 await命令后面的promise都执行完,整个async函数才能发生状态变化!
- async return出来的值会出现在 async的.then回调里面;async 抛出的异常,会被async 的catch回调接收到。
- 正常的 async 内部的 await后面都是跟着promise的,如果不是的话,会被转化成一个 立即resolve的promise!
- async 内部只要有一个await出现reject状态,后面的await都不会执行! ---> 为所有的await添加
try/catch
2. 下面通过直接的代码看看关于异步处理的这点事:
function fetchData(age) {
return new Promise((resolve, reject) => {
if (age < 30) {
const obj = {
code: 1,
age: age,
description: '恭喜!你的年级符合要求!'
}
resolve(obj);
} else {
const obj = {
code: -1,
age: age,
description: '抱歉,你的年纪不符合要求!'
}
reject(obj);
}
})
}
function calcuteAge(resAge) {
return new Promise((resolve, reject) => {
if (resAge.code === 1) {
resolve('根据你的年级符合要求,请你接下去准备面试')
} else {
reject('抱歉,你没有后续了!')
}
})
}
3. 我们先来看看Promise的多次then回调是怎么处理异步操作的:
fetchData(18).then(res => {
if (res.code === 1) {
calcuteAge(res).then(res => {
console.log(res);
})
}
})
4. 再来看看async/await
如何处理异步操作的:
async function filterPerson() {
let ageCondition = await fetchData(18);
let mettingOK = await calcuteAge(ageCondition);
return mettingOK;
}
filterPerson().then(res => {
console.log(res);
})
5. async/await
在内部await返回的不是promise,比如:抛出错误,纯纯的字符串... ,async又会怎么处理那?
async function error() {
throw new Error('我是抛出的错误');
}
error().then(res => {
console.log(res);
}).catch(err => {
console.log(err); // catch拦截错误提示
})
async function noPromise() {
return 'hahahah'
}
noPromise().then(res => {
console.log(res); // hahahah
})
6.解决sync地狱
试想这个案例:我们从选择披萨到购物车,然后付钱 并且选择可乐到购物车,生成订单付钱。。。这中间既有异步操作,也可以披萨可乐同步进行!
更好的处理逻辑是:将从【获取披萨列表+选择披萨+添加披萨到购物车+生成订单付钱】这个流程封装成一个关于披萨的异步函数,类似的还有关于可乐购物的整个流程的异步函数。
将selectPizza()及可乐selectDrink()的异步函数,通过
Promise.all()
,同步一起处理披萨和可乐即可!