最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AXIOS: how to run http requests concurrently and get the result of all requests event if a request fails - Stack Ov

programmeradmin0浏览0评论

I am trying to make server get requests concurrently, in order to do that I have written the following function.

Problem

If a single call is failing then I am not able to get the response of rest of the requests.

export const getAll = async (collection) => {
    return new Promise((resolve, reject) => {
        const requests = collection.map(req => {
            const config = {
                headers: req.headers,
                params: req.params
            }
            return axios.get(req.url, config);
        })

        axios.all(requests)
            .then(axios.spread((...args) => {
                // all succerss
                resolve(args);
            }))
            .catch(function (error) {
                // single call fails and all calls are lost
                reject(error)
            });
    })
}

Is it possible to get the result of all requests whether it fails or success?

I am trying to make server get requests concurrently, in order to do that I have written the following function.

Problem

If a single call is failing then I am not able to get the response of rest of the requests.

export const getAll = async (collection) => {
    return new Promise((resolve, reject) => {
        const requests = collection.map(req => {
            const config = {
                headers: req.headers,
                params: req.params
            }
            return axios.get(req.url, config);
        })

        axios.all(requests)
            .then(axios.spread((...args) => {
                // all succerss
                resolve(args);
            }))
            .catch(function (error) {
                // single call fails and all calls are lost
                reject(error)
            });
    })
}

Is it possible to get the result of all requests whether it fails or success?

Share Improve this question asked Oct 30, 2018 at 12:28 Vikas BansalVikas Bansal 11.8k16 gold badges63 silver badges107 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

In other words even if request fails you want to act rest of the code like request has succeed.

Let's assume that response cannot be null. Then we catch request's error and return null in this case for request.

export const getAll = async (collection) => {
    const requests = collection.map(req => {
        const config = {
            headers: req.headers,
            params: req.params
        };
        return axios.get(req.url, config).catch(() => null);
    })
    return axios.all(requests);
}

So if you have catch() and it does not throw exception all later code works like Promise has been resolved not rejected.

Also note you don't need to return Promise explicitly from async function because it happens automatically. Even more: since you don't have await inside the function you actually don't need it to be marked as async. And finally axios.all returns Promise so you don't need to resolve/reject Promise manually.

the way I've done this in the past is by wrapping the return value of my promise into an object that either has a result field or something similar and an err field:

export const getAll = async (collection) => {
    const requests = collection.map(req => {
        const config = {
            headers: req.headers,
            params: req.params
        }

        return axios.get(req.url, config)
            //wrap all responses into objects and always resolve
            .then(
                (response) => ({ response }),
                (err) => ({ err })
            );
    });

    return axios.all(requests)
        //note that .then(axios.spread((...args) => {}) is the same as not using
        //spread at all: .then((args) => {})
        .then(axios.spread((...args) => {
            //getAll will resolve with a value of
            //[{ response: {}, err: null }, ...]

            return args;
        }))
        .catch((err) => {
            //this won't be executed unless there's an error in your axios.all
            //.then block

            throw err;
        });
}

also see @skyboyer's post for some good points he's made about the rest of your code.

Here is the plete node js based example based on the Andrew solution:

const axios = require('axios');

const getAll = async (collection) => {
    const requests = collection.map(req => {
        const config = {
            // headers: req.headers,
            params: req.params
        }

        return axios.get(req.url, config)
        //wrap all responses into objects and always resolve
            .then(
                (apiResponse) => ({
                    apiResponse
                }),
                (apiError) => ({
                    apiError
                })
            );
    });

    return axios.all(requests)
    //note that .then(axios.spread((...args) => {}) is the same as not using
    //spread at all: .then((args) => {})
        .then(axios.spread((...args) => {
            //getAll will resolve with a value of
            //[{ response: {}, err: null }, ...]

            return args;
        }))
        .catch((axiosError) => {
            //this won't be executed unless there's an error in your axios.all
            //.then block

            throw axiosError;
        });
}

let api1 = {url: "http://localhost:3000/test?id=1001", param: ""};
let api2 = {url: "http://localhost:3000/test?id=1002", param: ""};
let api3 = {url: "http://localhost:3000/test?id=1003", param: ""};
let apis = [api1, api2, api3];

getAll(apis).then((res) => {
        console.log("getAll call finished");
        //console.log(res);
    }
);

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论