【问题标题】:Redux middleware async functionRedux 中间件异步函数
【发布时间】:2018-03-19 22:20:48
【问题描述】:

我有一个与 rest api 交互的 redux 中间件。我最近开始使用 async/await 重写一些 fetch 函数。

为了对我来说最有意义,我需要中间件函数本身是一个异步函数,这样我就可以在我创建的其他异步函数上使用“等待”和 try/catch 块,而不是拥有使用 .then、.catch。

到目前为止,我有这个:

const apiMiddleware = ({
  dispatch,
  getState
}) => next => async action => {
  switch (action.type) {
   //...
   }
  next(action);
};

请注意在“动作”之前使用 async 关键字。到目前为止,这似乎按预期工作,我可以等待该中间件的其他异步功能。但是,由于我无法找到这方面的文档,我想知道我所做的是否真的有效。

谢谢

【问题讨论】:

  • 在内部,你并没有真正做任何不同的事情,谢谢在解决后打电话给 next,所以我不明白为什么它不起作用
  • 我们有多个这样的异步中间件函数,最近开始遇到意外的行为。我们看到 redux 选择器被旧状态触发,大概是因为异步中间件函数影响了操作的处理顺序。

标签: javascript ecmascript-6 redux async-await redux-middleware


【解决方案1】:

您是否考虑过研究 Redux Sagas? https://redux-saga.js.org/

这是专门为使使用异步函数更易于管理而创建的。 而且我认为实现这一点可以使您的异步函数更易于理解,并且更易于调试。

您的代码是有效的 javascript,但由于函数的异步性质,您可能会遇到状态不一致的情况。

如果在调度下一个操作之前您的异步操作未完成,则第二个操作将使用状态的一个版本,该状态可能会在运行时被第一个操作改变。

这种行为可能会给您带来您所描述的问题。


编辑:在我得知你已经在使用 redux-thunks 之后

在 redux thunk 中,您可以链接动作调度、等待,并利用调度的返回。

本文中有关如何使用 redux-thunk 链接操作的示例:https://blog.jscrambler.com/async-dispatch-chaining-with-redux-thunk/

const dispatchChaining = () => async (dispatch) => {
  await Promise.all([
    dispatch(loadPosts()), // <-- async dispatch chaining in action
    dispatch(loadProfile())
  ]);

  return dispatch(updateDone());
};

const actions = redux.bindActionCreators({dispatchChaining}, store.dispatch);
actions.dispatchChaining().then(() => unsubscribe());

请注意,只要有返回,这些分派就可以执行。这里的好处是我们可以并行触发异步调度并等待两者完成。然后,更新 isDone 知道两个调用都已完成,没有任何不可预测的行为。这些可重用的 thunk 可以存在于 store 的不同部分以保持关注点分离。

【讨论】:

  • 嘿 Bjorn,您对为什么会发生这种奇怪行为的解释是正确的。但是,我们已经在使用 redux-thunk 进行异步操作。问题是我们并没有尝试在这里分派异步操作,我们正在尝试创建异步中间件,这可能会延迟操作的执行。这有意义吗?
  • @嘿汤姆!使用 redux thunk 的可能解决方案更新了答案。 :)
  • 谢谢比约恩。这解释了如何创建链接其他异步操作的新操作,但问题是我们正在尝试创建异步中间件。我们的用例是一个中间件,可确保我们在运行任何需要身份验证的 redux 操作之前进行身份验证。如果我们未通过身份验证,则应停止所有 redux 操作,直到我们通过身份验证,然后操作应照常恢复。我们正在尝试使用异步中间件函数(不是操作)来实现这种暂停操作。
  • @Tom 我可能听起来很蹩脚,但你能解释一下'redux 选择器被旧状态触发'的含义,因为选择器应该只在状态树的相关部分发生变化时触发是唯一的事实来源。
  • @deepanshu 不是 Bjorn 所说的“您的代码是有效的 javascript,但由于函数的异步性质,您可能会遇到状态不一致的情况。如果您的异步操作不是在调度下一个动作之前完成,第二个动作将使用状态的一个版本,在运行时可能会被第一个动作改变。” ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2023-03-23
  • 1970-01-01
  • 2017-07-28
  • 2018-09-29
  • 2016-04-24
  • 1970-01-01
相关资源
最近更新 更多