首页 > 解决方案 > Dispatch Redux Action by Promise.all 回调几个 API Endpoint

问题描述

我必须从多个端点获取多个数据,然后合并到将发送到减速器的单个数据,然后我得到 Promise.all,获取几个 api 数据然后合并,我的问题是,如何检测哪个是失败的哪个是成功的?那么哪个是成功的仍然发送到reducer,一个失败的发送失败消息

我使用 ReactJS、Redux 和 Redux Thunk,当所有端点都成功回调时,所有数据都已发送,但是当端点之一失败时,它只会抛出一个来自端点之一的错误

我做了什么:


const chartUrl = [
    requestAPI('GET', 'endpoint/a', 2).then(res => res.json()),
    requestAPI('GET', 'endpoint/b', 2).then(res => res.json()),
    requestAPI('GET', 'endpoint/c', 2).then(res => res.json()),
    requestAPI('GET', 'endpoint/d', 2).then(res => res.json()),
    requestAPI('GET', 'endpoint/e', 2).then(res => res.json()), // this endpoint fail
    requestAPI('GET', 'endpoint/f', 2).then(res => res.json()),
    requestAPI('GET', 'endpoint/g', 2).then(res => res.json())
];


let chartObj = {
        dataChart: {}
    };
Promise.all(chartUrl)
        .then(storeData => {
            let mergedData = storeData.reduce((prev, cur) => {
                prev[cur.message] = cur;
                return prev;
            }, {});
            Object.assign(chartObj.dataChart, mergedData);
            // Make detection which code=200 and success=true then dispatch to fetched_chart reducer, but when code != 200 and success=false then dispatch to fail_chart reducer
            console.log(chartObj);
        })
        .catch(err => {
            //when server has fail then dispatch to error_fetch_chart reducer
            return err;
        })

输出 :

http://web.data.net/api/v1/endpoint/interaction 500 (Internal Server Error)

我期望这样的输出:

{
  dataChart:
    {
      a: {
        code: 200,
        success: true
        data: chartA
      },
b: {
        code: 200,
        success: true
        data: chartB
      },
c: {
        code: 200,
        success: true
        data: chartC
      },
d: {
        code: 200,
        success: true
        data: chartD
      },
e: { //error callback
        message: '500 (Internal Server Error)'
    }
...
    }
}

标签: javascriptreactjsreduxpromise

解决方案


编辑:如果你想在失败的情况下中止,那么你可以像约翰在下面的评论中指出的那样捕捉并抛出。

如果您捕获每个请求Promise.all的拒绝,则不会在单个请求失败时拒绝。

// util for invoking the requestAPI, capturing the path in rejection
const req = (path, arg) => requestAPI('GET', path, arg)
    .then(req.json())
    .catch(e => ({ error: e, path, arg})) 

const chartUrl = [
  req('endpoint/a', 2),
  req('endpoint/b', 2),
  // etc.
];

那么你可以这样做:

Promise.all(chartUrl)
  .then(results => results.map((r, index) => {
    if (r.error) {
      // deal with failed individual request
      console.error(`request for ${r.path} failed.`)
    }
    else {
      // do something with successful result
    }
  })
)

推荐阅读