redux-thunk中间件源码
浅析redux-thunk中间件源码
大多redux的初学者都会使用redux-thunk中间件来处理异步请求,其理解简单使用方便(具体使用可参考官方文档)。我自己其实也一直在用,最近偶然发现其源码只有一个函数,考虑到其在Github上至今有6747个赞,因此比较好奇它究竟给出了一个怎么样的函数。
什么是thunk?
在看具体的源码之前,我们先看一个词thunk,理解这个词有助于我们理解源码。
A thunk is a function that wraps an expression to delay its evaluation. 维基百科中是这样解释
thunk的:thunk是一种包裹一些稍后执行的表达式的函数。
redux-thunk源码
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
redux-thunk的源码非常简洁,出去空格一共只有11行,这11行中如果不算上},则只有8行。最后三行模块的导出方法很好理解,
// thunk的内容如下
({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
} // thunk.withExtraArgument的结果如下
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
thunk.withExtraArgument允许给返回的函数传入额外的参数,它比较难理解的部分和thunk一样,如下:
({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
}
上述代码使用函数参数的解构加上连用三个箭头函数,显得非常简洁,单同时也带来了理解的困难(这也是箭头函数的缺点之一)。把上述代码在babel REPL中转译为ES5语法后,我们看到以下结果:
"use strict";
function createThunkMiddleware(extraArgument) {
return function (_ref) {
var dispatch = _ref.dispatch,
getState = _ref.getState;
return function (next) {
return function (action) {
if (typeof action === "function") {
return action(dispatch, getState, extraArgument);
}
return next();
};
};
};
}
这下,代码一下子我们能看懂了,不过稍等这里的dispatch,getState,next还有action又是什么?
我们先看看,在reudx中我们如何使用中间件:
let store = createStore(
reducer,
applyMiddleware(thunk)
);
看来,要解开dispatch,getState,next,action从哪里来,我们还需要再看看applyMiddleware的源码,如下:
export default function applyMiddleware(...middlewares) {
return (createStore) => (...args) => {
const store = createStore(...args)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
可以看出其中middleware执行时传入的参数对象middlewareAPI中确实包含getState和dispatch两项,next则来自dispatch = compose(...chain)(store.dispatch)这一句中的store.dispatch,而action在dispatch某个action时传入。
一般来说一个有效携带数据的action是如下这样的:
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
加入redux-thunk后,action可以是函数了,依据redux-thunk的源码,我们可以看出如果传入的action是函数,则返回这个函数的调用,如果本身传入的函数是一个异步函数,我们完全可以在函数调用结束后,获取必要的数据再次触发dispatch由此实现异步效果。
小结
redux-thunk的源码总的来说还是很简单的,理解这个函数本身并不难,但是在彻底弄懂每一项却需要对reudx的部分源码有所了解。react官方文档中的Middleware一节讲解的非常好,也确实帮我理解了中间件的工作原理,非常推荐阅读。之前一直使用redux-thunk做异步处理,这段时间尝试了一下redux-saga,它非常优雅,可用于处理更加复杂的异步action,之后有时间会再总结一下它的用法,如果可以,也愿意再分析下它的源码,欢迎关注。
redux-thunk中间件源码的更多相关文章
- laravel中间件源码分析
laravel中间件源码分析 在laravel5.2中,HTTP 中间件为过滤访问你的应用的 HTTP 请求提供了一个方便的机制.在处理逻辑之前,会通过中间件,且只有通过了中间件才会继续执行逻辑代码. ...
- Django-session中间件源码简单分析
Django-session中间件源码简单分析 settings里有关中间件的配置 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddlew ...
- 21.django中间件源码阅读
回顾: 关于里面的源码流程大家可以全看视频,因为代码的跳动性很大,而且会多次调用通过一方法,所以关于中间源码的部分去找个视频看一看,我写的不是很清楚. # 1 cookie session # 2 f ...
- Redux thunk中间件
redux-thunk https://github.com/reduxjs/redux-thunk Why Do I Need This? Thunks are the recommended mi ...
- 重新整理 .net core 实践篇——— 权限中间件源码阅读[四十六]
前言 前面介绍了认证中间件,下面看一下授权中间件. 正文 app.UseAuthorization(); 授权中间件是这个,前面我们提及到认证中间件并不会让整个中间件停止. 认证中间件就两个作用,我们 ...
- Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)
实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...
- Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)
实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...
- 基于django中settings中间件源码思想,实现功能的插拔式设计
这里我们用到一个非常重要的模块,importlib,利用它可以实现字符串转python代码,再利用反射进行操作,这样就可以实现插拔式设计. 一.我们先做个初级的,把所有文件放到初级思想文件夹下: 1. ...
- redux设计到源码 --- 美团点评技术团队(转)
https://tech.meituan.com/redux-design-code.html
随机推荐
- 离线安装Chrome 插件
说明: Postman不多介绍,是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件.本文主要介绍下安装过程. 本文使用的是解压文件直接进行安装.是比较快速有效的安装方式 第一步:把下载后 ...
- [Axiom 3D]1.初识Axiom
1. 简介 The Axiom 3D Rendering Engine is a fully object oriented 3D graphics engine using C# and the . ...
- PAT Sum of Number Segments[数学问题][一般]
1104 Sum of Number Segments(20 分) Given a sequence of positive numbers, a segment is defined to be a ...
- mysql数据库访问权限限制设置
---只能本地访问,设置随意访问 update user set host='%' where host='localhost': flush privileges; ---随意访问,设置只能本地访问 ...
- 单机部署PXC
在一台机器上安装PXC Linux:centos 7 IP:192.168.30.221 PXC版本:Percona-XtraDB-Cluster-5.7.17-rel13-29.20.3.L ...
- cocos代码研究(17)Widget子类RadioButtonGroup学习笔记
理论基础 RadioButtonGroup可以把指定的单选按钮组织起来, 形成一个组, 使它们彼此交互. 在一个RadioButtonGroup, 有且只有一个或者没有RadioButton可以处于被 ...
- java第八天
p41~p45: 1.区别前缀式与后缀式. public class Test { public static void main(String[] args) { int i = 1; System ...
- Java实现文本创建、删除、编辑内容
Java实现文本创建.删除.编辑内容 1,创建文本代码: //创建文件并追加内容 public static void writeContentToTxt(StringBuffer Content,F ...
- 20145204 《Java程序设计》第2周学习总结
20145204 <Java程序设计>第2周学习总结 教材学习内容总结 在第三章主要学习了Java语言中的类型及其变量主要类型为:整数(1字节的byte,2字节的short,4字节的int ...
- 20145325张梓靖 实验一 "Java开发环境的熟悉"
20145325张梓靖 实验一 "Java开发环境的熟悉" 程序设计过程 实验内容 实现凯撒密码,并进行测试 编写代码 使用java.util.Scanner进行输入,而它的方法里 ...