如何确保所有使用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
,two
和 three
是按相反顺序解析的承诺。那么对于Promise.all([one,two,three]).then(results=>...
,结果(解析promise 的值)将按照传递给Promise.all 的顺序排列。但是,如果您执行[one,two.three].forEach(p=>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 错误?