Skip to content

Instantly share code, notes, and snippets.

@Shuumatsu
Last active March 27, 2017 06:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shuumatsu/85772d96867b65c022192d8e70a76054 to your computer and use it in GitHub Desktop.
Save Shuumatsu/85772d96867b65c022192d8e70a76054 to your computer and use it in GitHub Desktop.

Koa 与 Redux 中间件的实现方式


koa-compose

首先看 koa会怎么对待 compose 后的中间件

https://gist.github.com/79823fb6223c11dbeaec0b17cfdb43a4

一个 koa app 通常只合成一次 fn,合成的 fn 会在每次有新的 http 请求时被调用

返回的 handleRequest 会作为 http.createServer 的参数

以下是关键的“合成”中间件的 compose 的源码

https://gist.github.com/5e0412e2c45183876c6603f6ea7ebadc

每次 http 请求调用的 fn 即是返回的 function(context, next),每一个向 koa app 添加的中间件的调用以此函数内的 dispatch 的形式。dispatch 的参数为对应中间件的下标。

index 在每一次 http 请求调用 fn 的时候初始化,用以保证我们的每一个中间件仅调用一次 next

为了能够 catch downstream errors,dispatch 会返回一个 promise,try/catch 块中的 Promise.resolve 保证了中间件不是 async function 的情况。

合成的 fn 的第二个参数 next 相当于最后的 middleware:

https://gist.github.com/1955742d152c7e0a9c2a769e0991dbfa


redux-compose

以 redux-thunk 为例

https://gist.github.com/f8028235d5e6f73cd2bcb93b8987556d

每个 middleware 会接收两个方法 dispatch and getState 作为 named arguments。传递方法来获得 store state 来保证每个 middleware 获得的 state 为最新的。

形如 ({ dispatch, getState }) => next => action => {}

再来看 redux 注册中间件的方式

https://gist.github.com/5d3b23c9aef1e15a95ad3d6242ca5fe5

redux 根据中间件将原本的 dispatch 包装起来了,实现的关键部分是 compose 函数

https://gist.github.com/d6f7e6928c791373a2c9e82c17d6fc1d

compose 的每个参数都形如 next => action => {},最后合成的结果也是同样形式。

每一个原来的中间件都接收其右的中间件作为其 next 参数,最右的中间件的 next 参数为合成的中间件接收的 next 参数(原来的 dispatch

https://gist.github.com/03d9bc903f1e1daa08e43eac4400467c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment