【问题标题】:What is the point of Redux Promise and Redux Promise Middleware?Redux Promise 和 Redux Promise Middleware 的意义何在?
【发布时间】:2018-05-05 11:00:26
【问题描述】:

我搜索了高低,但找不到明确的答案。

我已经设法了解 Redux 的机制,但是当我谈到 API 调用和异步操作创建者时,我被中间件困在承诺。

你能帮我把乱七八糟的东西弄好吗?

难题的相互矛盾的部分让我头疼:

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

  2. Dan 在“What is the difference between redux-thunk and redux-promise?”中说,即使没有中间件,我也可以使用 Promise——只需在动作创建器中管理它们。

  3. 在其他答案中,我发现了使用动作创建者返回的 thunk 的示例... promise(后来在调用者 /dispatch(myActionCreator(params) .then(...)/ 所以一个承诺可以被一个thunk返回没有任何redux-promise lib..?

  4. 在“What is the difference between redux-thunk and redux-promise?”中,接受的答案是 Redux Thunk 返回函数,而 Redux Promise 返回 Promise.. 到底是什么?

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

更新:

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

【问题讨论】:

    标签: redux redux-thunk redux-promise redux-promise-middleware


    【解决方案1】:

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

    基本的 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(),并且每个中间件都可以使用传递给dispatch的任何值做任何事情:modify it, log it, delay it, or dispatch something else instead it。这意味着中间件可以“教”dispatch() 如何通过拦截值并执行其他操作来接受普通操作对象的内容。

    所以,redux-thunk“教导”dispatch 如何接受函数,方法是拦截函数并调用它,而不是将其传递给减速器。 redux-promise "teaches" dispatch 如何接受 Promise,通过拦截 Promise 并在 Promise 解决或拒绝时调度操作。

    通常,dispatch 返回传入的任何操作对象。因为中间件环绕 dispatch,它们还可以更改返回的值。 redux-thunk 将运行 thunk 函数,并返回 thunk 函数返回的任何内容。这让你可以做一些有用的事情,比如从一个 thunk 中返回一个 Promise,并从那里链接行为:

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

    有关该主题的更多信息,请参阅Redux FAQ entry on dealing with side effects,以及我的React/Redux links listRedux Side Effects 部分中的文章。

    【讨论】:

    • 马克,这正是我对整个机制的描绘——分派本机接受 PO,当动作创建者返回其他内容时,中间件“弹出”。让我感到困惑的是您在示例代码 someThunkReturningAPromise 中显示的情况 - 从 thunk 返回一个承诺并使用 THEN 处理它,其中 no redux-promise 中间件存在 /only redux-thunk/ .我发誓我看到过这样的 tuts .. 也许我忽略了某事或使用 redux-promise 被认为是显而易见的.. 总而言之,要使 dispatch(someThunkReturningAPromise().then..) 工作,必须使用 redux-promise?
    • 没有。这需要redux-thunk。澄清一下:redux-promise 让您可以将 Promise 直接传递给 dispatch(),或将 Promise 放入操作对象中。 redux-thunk 允许您将函数直接传递给 dispatch(),并使 dispatch() 返回 thunk 函数返回的任何内容(可能是一个值,可能是一个承诺,或其他东西)。
    • 如果我用redux-promise 直接向dispatch() 传递一个承诺,那么redux-promise 会“启动”并处理它的解决/拒绝?附言。直到现在我才注意到,实际上从一开始我就错误地放置/看到了包含dispatch() args dispatch (...then(....)**)** 的括号,而实际上.then附加 以调度..
    【解决方案2】:

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

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

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

    因此,在我们从动作创建者返回动作后,在未来的某个时间,我们会从 JSON API 获得响应。

    因此,在发出 Ajax 请求和从动作创建者返回 Action 之间可能是瞬时的,但从动作创建者返回 Action 和收到 JSON API 响应之间的时间可能会更长。

    无论花费多长时间,当动作出现在 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;
      }
    }
    

    当我单击 Fetch Comments 按钮时,它调用了动作创建者,在我的源选项卡中,我立即点击了 debugger 语句。

    这里有证据表明,每当此操作出现在 reducer 中时,它都会获得从 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,这意味着我们的请求仍在网络上等待从 JSON API 返回。很明显,如果没有 Redux Promise 中间件,我们的应用程序将无法按预期工作。

    Action 创建者不是为了支持异步请求而开发的,我不知道这叫疏忽。

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

    【讨论】:

    • 感谢 Daniel 全面而慷慨的解释!
    • 我们不能没有中间件也能做到这一点,像这样:api.then(response=>{dispatch(response)}。那么,消除对中间件的需要?
    • 呵呵,我觉得这些代码示例看起来非常熟悉,然后在读完这篇文章后不久,我在 Udemy 的“高级 React 和 Redux”课程中找到了这个解释的确切点!
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2017-05-13
      • 2017-10-26
      • 1970-01-01
      • 2019-01-03
      • 2017-07-29
      • 1970-01-01
      • 2016-08-03
      • 2017-07-07
      • 2018-05-27
      相关资源
      最近更新 更多