Redux Promise 和 Redux Promise 中间件有什么意义?

What is the point of Redux Promise and Redux Promise Middleware?

我到处搜索,但找不到明确的答案。

我已经设法了解了 Redux 的机制,但是 当我谈到 API 调用和异步动作创建者时,我在 Promises 的上下文中被中间件困住了。

你能帮我整理一下吗?

让我头疼的自相矛盾的拼图:

  1. 一个 YT 教程说原生 Redux 调度方法不支持从动作创建者返回的承诺——因此需要 Redux Promise 库(我知道这个项目现在可能已经死了,继续是Redux Promise 中间件).

  2. Dan 在“”中说即使没有中间件我也可以使用 promises——只需在 action creator 中管理它们即可。

  3. 在其他答案中,我找到了使用 thunk 的示例,其中动作创建者返回了... promise(稍后在调用者中处理 /dispatch(myActionCreator(params).then(...)/ 所以一个 promise can 由一个 thunk WITHOUT 返回任何 redux-promise lib..?

  4. 在“”中,接受的答案指出 Redux Thunk returns 函数,而 Redux Promise returns promises.. 到底是什么?

总结一下:使用 Redux Promise 或 Redux Promise 中间件有什么意义?为什么 Redux 本身不支持 promises?

更新:

我刚刚意识到在上面的第 3 点我忽略了 then() 附加 dispatch 而不是 包含 dispatch() 参数中。

链接的答案是正确的,但我会尝试进一步解释。

一个基本的 Redux 存储将接受分派普通对象操作:

store.dispatch({type : "ADD_TODO", text : "Buy milk"});

如果您尝试传递普通对象操作以外的任何内容,商店将抛出错误:

store.dispatch(() => {});
// Error: "Actions must be plain objects. Use custom middleware for async actions."

Middleware form a pipeline around store.dispatch(), and each middleware can do anything it wants with whatever value was passed to dispatch: modify it, log it, delay it, or dispatch something else instead it。这意味着中间件可以 "teach" dispatch() 如何接受 不是 普通操作对象的东西,方法是拦截值并做其他事情。

因此,redux-thunk "teaches" dispatch 如何接受函数,通过拦截函数并调用它而不是将其传递给 reducer。 redux-promise "teaches" dispatch 如何接受承诺,通过拦截承诺并在承诺解决或拒绝时调度操作。

通常,dispatch return 传递传入的任何操作对象。因为中间件环绕 dispatch,它们还可以更改正在 returned 的值。 redux-thunk 将 运行 thunk 函数,并且 return 无论那个 thunk 函数 returns。这让你可以做一些有用的事情,比如 return 来自 thunk 的承诺,以及从那里开始的连锁行为:

dispatch(someThunkReturningAPromise())
    .then(() => {
        // Do more stuff here
    });

有关该主题的更多信息,请参阅 Redux FAQ entry on dealing with side effects, and the articles in the Redux Side Effects section of my React/Redux links list

你需要这些中间件来避免竞争条件,因为 javascript 是异步的。它们之间的区别只是实现,thunk 使用函数,sagas 使用生成器等

当您调用动作创建器(动作创建器函数的第一行)时,您会发出 ajax 请求。这是一个网络请求,将到达 JSON API.

要理解的关键部分是,当我们发出该请求时,我们进入下一行代码,我们在其中形成该操作对象并 return 它。这两个步骤之间的时间,即发出请求和 return 执行操作之间的时间是瞬时的。

如您所知,每当我们向外部API发出网络请求时,可能需要一些时间才能得到响应。

因此,在我们 return 从操作创建者处执行操作后,在未来的某个时刻,我们会从 JSON API.

因此,在发出 Ajax 请求和从动作创建者 return 编辑动作之间可能是瞬时的,但是从动作创建者 return 编辑动作到 JSON API 收到可能需要更长时间。

无论需要多长时间,当 action 出现在 reducer 内部时,它总是可以从我们的 API.

中获取我们的数据

为了给你一个更好的主意,我在我自己的一个 reducer 中添加了一个 debugger 语句,这样我们就可以查看其中的不同值。

import { SAVE_COMMENT, FETCH_COMMENTS } from 'actions/types';

export default function(state = [], action) {
  switch (action.type) {
    case SAVE_COMMENT:
      return [...state, action.payload];
    case FETCH_COMMENTS:
      debugger;
      const comments = action.payload.data.map(comment => comment.name);
      return [...state, ...comments];
    default:
      return state;
  }
}

当我单击“获取评论”按钮时,它调用了动作创建器,在我的源选项卡中,我立即点击了 debugger 语句。

这里有证据表明,每当此操作出现在减速器中时,它都会收到来自 API 的响应。

现在,让我们删除 Redux Promise 中间件,看看会发生什么。

中间件:

export default ({ children, initialState = {} }) => {
  const store = createStore(
    reducers,
    initialState,
    applyMiddleware(reduxPromise)
  );

中间件消失了:

export default ({ children, initialState = {} }) => {
  const store = createStore(reducers, initialState, applyMiddleware());

  return <Provider store={store}>{children}</Provider>;
};

这是什么?

payload 不是从 JSON API 返回的响应,而是待处理的 Promise,这意味着我们的请求仍在网络上等待从JSONAPI回来。很明显,如果没有 Redux Promise 中间件,我们的应用程序将无法按预期运行。

Action creators 不是为支持异步请求而开发的,我不知道这是一个疏忽。

我们使用像 Redux Promise 这样的中间件来查看即将发送到 reducer 的动作,我们有机会延迟、记录、修改或完全停止该动作,而且只有通过这些中间件,我们才能做到这些异步请求以我们期望的方式工作。我们正在使用 Redux Promise,因为我们想检查每个动作 returned 从动作创建者,如果它包含一个 API 请求或一些异步请求,我们想延迟它,所以我们可以得到那个响应在动作继续到减速器之前回来。这就是 Redux Promise 为我们所做的。