如何确保所有使用redux的promise中的promise顺序正确?

Posted

技术标签:

【中文标题】如何确保所有使用redux的promise中的promise顺序正确?【英文标题】:How to assure correct order of promises in promise all using redux? 【发布时间】:2018-11-14 05:06:19 【问题描述】:

我正在使用 redux(并做出反应),我必须多次发出多个 api 请求。我正在使用 for 循环并承诺所有。正在解决的订单承诺是问题,因为订单是随机的 - 首先第二个承诺得到解决,然后是第一个,然后是第三个而不是 1,2,3。 我做错了什么还是如何更改订单?另外,当我没有收到任何数据时,停止迭代的方法是什么?我将不得不迭代大约 25 次,但不想对其进行硬编码。我可以用我的渔获来确定吗?非常感谢!

行动:

export const fetchData = () => 
    return dispatch => 
        const promises = [];

        dispatch(type: FETCHING_DATA)

        for (var i = 0; i < 3; i++) 
            const start = i === 0 ? 0 : (i + "01");
            let getData = axios.get(`$api_root_url/v1/?start=$start`)    
                .then(res => 
                    dispatch(type: FETCH_DATA_SUCESS, payload: res.data)
                )
                .catch(err => 
                    dispatch(type: FETCH_DATA_ERR, payload: err.data)
                )
            promises.push(getData)
        
        return Promise.all(promises)    
    

【问题讨论】:

如果顺序很重要,不要使用Promise.all,.. 而是链接你的承诺,。如果你可以使用async / await,这真的很简单。 你不能使用Promise.all()一个固定的顺序。 另一种选择,如果你可以等到所有承诺完成,你可以在你的Promise.all..之后调度。Promise.all的返回顺序是一致的,只是不是承诺执行的顺序. 如果可以,请使用 async/await,否则您可以使用 bluebird 的 Promise.each() 代替 Promise.all() 来确保每个 Promise 根据它在 Promise 数组中的顺序按顺序执行:@987654321 @ 这是由用户动作发起的动作吗?问题在于用户可以启动动作 ABC,然后这些动作的承诺按 ACB 顺序解决,因此用户的最后一个动作是 C,但 UI 显示 B 的结果。这个问题及其解决方案在this pen click 中演示5 并在 5 秒内单击 1 按 F12 并查看由这些操作启动的单击顺序和已解析异步代码的顺序。 【参考方案1】:

如果在解决 3 个请求时分派的操作顺序很重要,您可以尝试 2 件事:

在所有 3 个操作都完成后发送操作:

export const fetchData = () => 
    return dispatch => 
        const promises = [];

        dispatch(type: FETCHING_DATA);
        Promise.all(
          [...new Array(3)].map((ignore,i)=>i === 0 ? 0 : (i + "01"))
          .map(
            start=>axios.get(`$api_root_url/v1/?start=$start`)
          )  
        ).then(
          results=>results.forEach(
            result=>
              dispatch(type: FETCH_DATA_SUCESS, payload: result.data)
            )
        ).catch(
          err => dispatch(type: FETCH_DATA_ERR, payload: err.data)
        );
        //not sure why you want to return something here
        //return Promise.all(promises)    
    

或者保持你的代码原样,但是在dispatch(type: FETCH_DATA_SUCESS, payload: result.data)添加什么请求已经完成,这样reducer就知道在哪里更新状态。 dispatch(type: FETCH_DATA_SUCESS, payload: request_from:start,data:res.data) 之类的东西,catch 语句也一样。

【讨论】:

非常感谢,我使用了您的代码,现在正在按顺序获取结果。您能否解释一下,为什么为所有已解决的承诺分派代理会导致一个有序列表,以及为什么当我像我之前那样分派操作时它没有这样我理解得更好?谢谢!! @javascript2016 说 one,twothree 是按相反顺序解析的承诺。那么对于Promise.all([one,two,three]).then(results=&gt;...,结果(解析promise 的值)将按照传递给Promise.all 的顺序排列。但是,如果您执行[one,two.three].forEach(p=&gt;p.then(console.log(resolve)),它将记录三个、两个、一个,因为当一个承诺解决时,console.log 会立即记录解决。 Promise.all([array of promises]) 将在数组中的所有 promise 都被解析时解析,然后解析值传递数组的顺序。 @javascript2016 都在.then的位置 好的,我明白了。感谢您的解释!只是一个侧面问题:到目前为止,我对这一点进行了硬编码,直到它应该迭代为止,因为我知道我收到了多少数据,这很糟糕,因为数据量可能会发生变化。有没有一种方法可以迭代到我没有收到数据/捕获会被触发的地步? @javascript2016 这取决于你的 api,也许它返回空,也许它返回一个错误,但 json 中有错误的成功响应,可能是任何东西。正如您在另一个问题中所评论的那样:这些似乎是您在错误的一端解决的问题。我猜你正在使用一个你无法控制的 API。

以上是关于如何确保所有使用redux的promise中的promise顺序正确?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 redux 和 redux-promise 将多个 axios 调用合并到一个有效负载中?

如何确保 Node.js 中的这些函数链按顺序执行(使用 Promise)?

使用 redux-thunk 从 React Native 中的动作创建者返回 Promise

如何在 reducer 中处理 Redux 的 redux-promise 中间件 AJAX 错误?

如何使用 rxjs 和 redux observable 实现 Promise 类型的场景?

redux-promise:未捕获的 TypeError:中间件不是函数