Redux-thunk 源码解读

阅读时长 8 分钟读完

Redux-thunk 是一个 Redux 的中间件,它允许我们在 Redux 的 action 创建函数中返回一个函数而不是一个对象。返回的这个函数可以接受其它引用数据,例如 dispatchgetState,并在这个函数中执行异步逻辑,并 dispatch 其它的 action,从而最终改变应用的状态。

在本篇文章中,我们将对 Redux-thunk 中的源码进行深入的解读,并希望读者在阅读本篇文章之后,能够对 Redux-thunk 的内部工作原理有更加深入的理解,并且可以在自己的项目中更好地使用和调试 Redux-thunk。

关于 Redux-thunk

在 Redux 应用中,我们通常会通过在组件内部定义 action 创建函数来 dispatch action,例如:

这样的 action 可以在组件内部通过调用 dispatch 来改变应用的状态。

但是在应用中,我们有时会遇到需要处理异步操作的情况,例如在用户登录操作中,需要先向服务器发送请求,等到服务器返回结果之后再 dispatch action,才能真正地改变应用的状态。

这个时候 Redux-thunk 中间件就派上用场了。

通过在 action 创建函数中返回一个函数,示例如下:

在这个示例中,我们返回了一个函数,它接受 dispatch 作为第一个参数,并且在函数体内部执行异步操作,然后 dispatch 其它的 action,最后返回了一个 Promise 对象,方便我们在外部使用 then 方法来判断操作是否完成。

Redux-thunk 通过将返回的函数注入 dispatchgetStateextraArgument 等参数,让我们可以灵活地进行异步逻辑的处理。

深入 Redux-thunk 源码

接下来,我们将深入 Redux-thunk 中间件的源码,了解其内部实现。

首先,在使用 Redux-thunk 中间件时,我们通常要先使用 applyMiddleware 函数将 Redux-thunk 中间件注册到应用中:

applyMiddleware 函数中,会对传入的中间件进行格式化,使得它们可以正确地被应用。

-- -------------------- ---- -------
------ ------- -------- ------------------------------- -
  ------ ----------- -- --------- -- -
    -- ---
    ----- ----- - --------------------

    --- -------- - -- -- -
      ----- --- ------
        ------------ ----- ------------ ---- ---------- -- --- -------- - -
        ------ ---------- ----- --- -- ------- -- ---- ----------
      -
    -

    ----- ------------- - -
      --------- ---------------
      --------- --------- -- -----------------
    -
    -- ---
  -
-

在这个函数中,我们可以看到在创建 Redux 的 store 时,会先定义一个 dispatch 方法,这个方法的内部实现是抛出一个错误。

接着,我们将 getState 和这个 dispatch 方法以 middlewareAPI 的形式注入到 next 函数中:

在此过程中,middlewares 是一个包含所有中间件的数组,在 Redux-thunk 应用中,它的值为 [thunk]

在每一个中间件函数中,我们都可以接受一个 { getState, dispatch } 形式的参数对象,在 Redux-thunk 应用中也是一样的。

接着进入到最重要的 Redux-thunk 源码部分:

-- -------------------- ---- -------
-------- ------------------------------------ -
  ------ -- --------- -------- -- -- ---- -- ------ -- -
    -- ------- ------ --- ----------- -
      ------ ---------------- --------- ---------------
    -

    ------ -------------
  --
-

----- ----- - ------------------------
----------------------- - ----------------------

------ ------- ------

在函数 createThunkMiddleware 中,我们定义了一个接受 extraArgument 参数的函数,并在它的返回值中定义了一个三级嵌套的函数结构:

  • 第一层函数接受的参数为注入到这个中间件中的参数对象 { dispatch, getState }
  • 第二层函数接受的参数为应用中的下一个中间件的 next 函数,该函数用于执行下一个中间件或最终的 dispatch 函数。
  • 第三层函数接受的参数为当前的 action,如果当前的 action 是一个函数,则说明这是一个异步操作,我们需要通过执行返回的函数来修改应用的状态。

createThunkMiddleware 函数中,我们首先定义了一个函数 thunk,返回值即为上述结构的第一层函数,并且定义了一个名为 thunk.withExtraArgument 的函数,用于返回一个接受额外参数 extraArgument 的 Redux-thunk 中间件函数。

在第一层函数中,我们返回了一个函数,这个函数接受 next 作为参数,并且在其内部返回了一个函数,这个函数接受 action 作为参数。

在对传入的 action 进行判断之后,如果它是一个函数,我们将会执行它,并在参数中注入了 dispatchgetStateextraArgument 参数,从而使得这个函数可以通过调用 dispatch 函数来 dispatch 其它的 action,最终改变应用的状态。

在执行这个函数之后,我们将其返回值作为异步操作的 Promise 对象,方便在外部对异步操作是否完成进行判断。

如果 action 不是一个函数,我们将会使用 next 函数来将它转发给下一个中间件来处理,并最终传递到最终的 dispatch 函数。

Redux-thunk 在实际开发中的应用

在实际的开发中,我们通常会通过 async/await 或者 Promise 的方式来处理对象的异步操作,例如:

-- -------------------- ---- -------
------ --- ---- -------

----- --------- - ---------- --------- -- ----- -------- -- -
  ---------- ----- --------------- --
  --- -
    ----- ------------------- ---------
    ---------- ----- --------------- --
  - ----- ----- -
    ---------- ----- --------------- --
  -
-

在这个例子中,我们使用了 async/await 的方式来处理对象的异步操作,并且在 catch 中 dispatch 其它的 action,使用了最新的语法特性,更加优美和易读。

总结

Redux-thunk 是一个方便我们处理 Redux 异步操作的中间件,它通过在 action 创建函数中返回一个函数的形式,支持异步操作以及 dispatch 其它的 action,并提供了一些额外的参数来支持更加灵活的处理异步逻辑。

在 Redux-thunk 的源码中,我们深入了解了中间件的实现方式,并且可以更清晰地了解到 Redux-thunk 是如何拦截 action 并处理异步逻辑的。

在实际开发中,我们可以使用最新的语法特性来编写异步操作代码,并且可以更好地利用 Redux-thunk 的特性,来轻松地处理复杂的异步逻辑。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64cdea89b5eee0b5255dd1c8

纠错
反馈