前端开发之axios并发请求的处理

2,377 阅读2分钟

背景

今天开发一个页面,这个页面有很多个请求,但彼此直接有着相互关联的关系,我需要拿到A请求返回的东西做一些处理再把处理后的数据拿去请求B接口,还有一些C、D、E的接口彼此之间又没有关系,我该如何处理这些请求呢?
最简单的办法:

import axios from 'axios'

...
async request () {
    const A = await axios(接口A);
    /*
        ......
        处理A请求数据
    */
    const B = await axios(接口B, A请求处理完的数据)
    await axios(接口C)
    await axios(接口D)
    await axios(接口E)
}
...

上面的代码运行起来没有问题,但...

能有好一点的办法么?

上面的代码是顺序执行的,会依次的执行,但是下面的C、D、E接口请求中,若其中某个接口响应很慢,后面的接口请求就会被阻塞。

并发请求我们通常会用Promise.all来做,Promise.all可以同时执行多个异步方法,而且会得到一个数组,数组中就是这些异步方法的返回值,Promise.all会等待这些异步方法都执行完毕才生成这个数组。

于是我们对上面的这段代码使用Promise.all进行改造:

import axios from 'axios'

...
async request () {
    const A = await axios(接口A);
    /*
        ......
        处理A请求数据
    */
    const B = await axios(接口B, A请求处理完的数据)
    // 将要进行promise.all的队列方法全部装进一个arr:
    const arr = [axios(接口C),axios(接口D),axios(接口E)]
    // resArr里面将会是[第一个方法的return值,第二个方法的return值, 第三个方法的return值]
    let resArr = await Promise.all(arr);
}
...

但我想说的还不止这些

image.png

上面使用promise.all是因为我们要获得并发的返回值,但如果,这些异步方法都没有返回值,或者我们不需要它们的返回值,我们只需要执行这些方法就行了:

import axios from 'axios'

...
async request () {
    const A = await axios(接口A);
    /*
        ......
        处理A请求数据
    */
    const B = await axios(接口B, A请求处理完的数据)
    // 去掉await不就是并发请求了么?
    axios(接口C)
    axios(接口D)
    axios(接口E)
}
...

一个demo代码:
async test() {
    let arr = [];
    for (let i = 0; i < 50; i++) {
        arr.push(delay1000(i));
    }
    arr.push(delay10000('没想到吧!'));
    arr = await Promise.all(arr);
    await delay1000(999);
    await delay1000(888);
    await delay1000(777);
    await delay1000(666);
    await delay1000(555);
    console.log(arr);
}

delay1000(n) {
    console.log(n);
    return new Promise((r, j) => {
        console.log('start');
        setTimeout(() => {
            console.log('time out !');
            r(n);
        }, 1000);
    });
}

delay10000(n) {
    console.log(n);
    return new Promise((r, j) => {
        console.log('start.。。。');
        setTimeout(() => {
            console.log('time out !');
            r(999999);
        }, 10000);
    });
}