【问题标题】:Dispatch Redux Action by Promise.all callback several API EndpointDispatch Redux Action by Promise.all 回调几个 API Endpoint
【发布时间】:2019-09-09 11:10:51
【问题描述】:

我必须从多个 Endpoint 获取多个数据,然后合并到单个数据将发送到 reducer,然后我得到 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)'
    }
...
    }
}

【问题讨论】:

  • Promise.all 如果有 any 个 promise 拒绝,则拒绝。我的第一个想法是在每个承诺上加上.catch,这样一次失败就不会导致整个事情失败。
  • 你可能想要Promise.allSettled,它在 chrome 中可用,但很容易被“填充”

标签: javascript reactjs redux promise


【解决方案1】:

编辑:如果你想在失败的情况下中止,那么你可以在下面的评论中捕捉并抛出 John points out

如果您发现每个请求都被拒绝,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
    }
  })
)

【讨论】:

  • 你就不能直接把链子扔到承诺的尽头吗?
  • 嗯。不接不接和不接不一样吗?
  • 好吧,假设每个人都不需要自己做其他事情。 (例如发送错误)。
  • 哦。正确的。正确的。我正在考虑即使一个请求失败也要继续。如果你想中止整个事情,那么确定。你可以捕捉到哪一个失败并扔掉它。
  • 是的,而且每个都可以单独使用,因为它们有自己的捕获。你的解决方案也很好:)
猜你喜欢
  • 2019-08-24
  • 2018-09-03
  • 2023-03-23
  • 2020-07-21
  • 2021-11-05
  • 2016-12-10
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多