在项目中,会有很多情况是需要请求多个接口并存在依赖情况,有的是下一个请求要使用上一个请求的结果,需要串行。有的是要某几个执行完再执行别的操作,需要并行。下面以定时器模拟请求接口,总结几种将异步转为同步方法:
let num1 = 1;
let num2 = 2;
// get1请求、get2请求
function get1 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
num1 += 1
console.log('get1要2s执行')
resolve(num1)
}, 2000)
})
}
function get2 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
num2 += 2
console.log('get2要1s执行')
resolve(num2)
}, 1000)
})
}
1、异步请求,不存在依赖关系
get1()
get2()
console.log('aaa')
// aaa
// get2要1s执行
// get1要2s执行
此时get1和get2会按顺序依次执行,虽然get1先执行,但是get1延迟了2s,get2只有1s,所以会先执行完get2。在实际项目中并不能确认他俩谁先返回结果,具体要看当时的网络和接口情况。
2、两个请求都要执行完(不需要谁先谁后)才进行下一步操作:Promise.all()
Promise.all([get1(), get2()])
.then((response) => {
console.log(response)
})
.catch(err => {
console.log(err)
})
// get2要1s执行
// get1要2s执行
// [2, 4]
then的函数体会在get1和get2的回调完成后执行,参数response是get1和get2的resolve()参数值组成的数组
3、两个请求要按照先后顺序执行完才进行下一步操作:await
async function get3(){
await get1()
await get2()
console.log('11111')
}
get3()
// get1要2s执行
// get2要1s执行
// 11111
此时虽然get2延迟只有1s,但是也会等get1执行完,再顺序执行get2,最后是console.log。同样适用Promise.all()也能有同样效果,但是不要忘了加await。如果不加await就会异步执行,先后顺序不能确定。
async function get3 () {
Promise.all([await get1(), await get2()]).then((data) => {
console.log(data)
})
}
get3()
// get1要2s执行
// get2要1s执行
// [2, 4]
4、两个请求都请求拿到数据才执行第三个请求
async function get3 () {
const res1 = await get1()
const res2 = await get2()
if(res1.code===200 && res2.code===200){
console.log('两个都拿到数据了')
}
}
get3()
以接口返回code200未正确获取到数据为例,当两个都正确拿到数据了才会执行 console.log(‘两个都拿到数据了’)。如果是断网或者请求出错等问题,使用第2个案例,使用Promise.all().then().catch