# redux中间件以及redux-saga

By [Murraya](https://paragraph.com/@murraya) · 2022-05-11

---

中间件：类似于插件，可以在不影响原本功能、并且不改动原本代码的基础上，对其功能进行增强。在Redux中，中间件主要用于增强dispatch函数。

实现Redux中间件的基本原理，是更改仓库中的dispatch函数。

Redux中间件书写：

*   中间件本身是一个函数，该函数接收一个store参数，表示创建的仓库，该仓库并非一个完整的仓库对象，仅包含getState，dispatch。该函数运行的时间，是在仓库创建之后运行。
    
*   由于创建仓库后需要自动运行设置的中间件函数，因此，需要在创建仓库时，告诉仓库有哪些中间件
    
*   需要调用applyMiddleware函数，将函数的返回结果作为createStore的第二或第三个参数。
    
*   中间件函数必须返回一个dispatch创建函数
    
*   applyMiddleware函数，用于记录有哪些中间件，它会返回一个函数
    
*   该函数用于记录创建仓库的方法，然后又返回一个函数
    

redux-saga
==========

> 中文文档地址：[https://redux-saga-in-chinese.js.org/](https://redux-saga-in-chinese.js.org/)

*   纯净
    
*   强大
    
*   灵活
    

![](https://storage.googleapis.com/papyrus_images/3d7083163db1229efc7aa1da4772c31ff6bb6150ac3e93bb34d01073726af766.png)

在saga任务中，如果yield了一个普通数据，saga不作任何处理，仅仅将数据传递给yield表达式（把得到的数据放到next的参数中），因此，在saga中，yield一个普通数据没什么意义。

saga需要你在yield后面放上一些合适的saga指令（saga effects），如果放的是指令，saga中间件会根据不同的指令进行特殊处理，以控制整个任务的流程。

每个指令本质上就是一个函数，该函数调用后，会返回一个指令对象，saga会接收到该指令对象，进行各种处理

**一旦saga任务完成（生成器函数运行完成），则saga中间件一定结束**

*   take指令：【阻塞】监听某个action，如果action发生了，则会进行下一步处理，take指令仅监听一次。yield得到的是完整的action对象
    
*   all指令：【阻塞】该函数传入一个数组，数组中放入生成器，saga会等待所有的生成器全部完成后才会进一步处理
    
*   takeEvery指令：不断的监听某个action，当某个action到达之后，运行一个函数。takeEvery永远不会结束当前的生成器
    
*   delay指令：【阻塞】阻塞指定的毫秒数
    
*   put指令：用于重新触发action，相当于dispatch一个action
    
*   call指令：【可能阻塞】用于副作用（通常是异步）函数调用
    
*   apply指令：【可能阻塞】用于副作用（通常是异步）函数调用
    
*   select指令：用于得到当前仓库中的数据
    
*   cps指令：【可能阻塞】用于调用那些传统的回调方式的异步函数
    
*   fork：用于开启一个新的任务，该任务不会阻塞，该函数需要传递一个生成器函数，fork返回了一个对象，类型为Task
    
*   cancel：用于取消一个或多个任务，实际上，取消的实现原理，是利用generator.return。cancel可以不传递参数，如果不传递参数，则取消当前任务线。
    
*   takeLastest：功能和takeEvery一致，只不过，会自动取消掉之前开启的任务
    
*   cancelled：判断当前任务线是否被取消掉了
    
*   race：【阻塞】竞赛，可以传递多个指令，当其中任何一个指令结束后，会直接结束，与Promise.race类似。返回的结果，是最先完成的指令结果。并且，该函数会自动取消其他的任务

---

*Originally published on [Murraya](https://paragraph.com/@murraya/redux-redux-saga)*
