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
随机推荐
- 001-ant design安装及快速入门【基于纯antd的基本项目搭建】
一.安装使用 1.1.安装 推荐使用 npm 或 yarn 的方式进行开发 npm install antd --save yarn add antd 1.2.浏览器引入 在浏览器中使用 script ...
- The adidas NMD Singapore is one of the brands top selling
Like pointed out, we've two adidas NMD Singapore releases using the first arriving Blue and Black as ...
- cocos代码研究(8)持续动作子类学习笔记
理论部分 时间间隔动作(ActionInterval)是一个在一段时间内执行的动作. 它有一个开始时间和完成时间.完成时间等于起始时间加上持续时间. ActionInterval的子类与位置有关的动作 ...
- 系统管理命令之w
区别于who命令,w命令不仅可以看到登录服务器的用户信息,而且可以看到这些用户做了什么 1.查看该命令的帮助信息. # w --help 2.查看该命令的版本信息. # w --version 3 ...
- 系统管理命令之who
作为一名系统管理员,我们需要弄清楚在一个特定的时间点都有谁活跃在系统上.必须严密监视我们的服务器.但是,我们当然不可能一天24小时都盯着系统.在linux系统中,我们可以使用who命令查看登录者信息. ...
- 表单验证—html5新特性表单验证
一.表单 <body> <section id="register"> <div><img src="images/logo.j ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 Solution
A - Buy and Resell 题意:给出n个交易点,每次能够选择买或者卖,求获得最大利润 思路:维护两个优先队列,一个是卖,一个是替换,当价格差相同时,优先替换,因为次数要最少 #includ ...
- 2017ACM/ICPC Guangxi Invitational Solution
A: A Math Problem 题意:给出一个n,找出有多少个k满足kk <= n 思路: kk的增长很快,当k == 16 的时候就已经超过1e18 了,对于每一次询问,暴力一下就可以 ...
- centos远程访问mssql数据库
http://blog.path8.net/archives/5921.html http://www.jaggerwang.net/2013/03/18/centos%E4%B8%8B%E5%AE% ...
- C#——JSON操作类简单封装(DataContractJsonSerializer)
Framework版本:.Net Framework 4 使用DataContractJsonSerializer时,实体请使用注解,格式如下 1.实体使用注解,并且提供get和set的public访 ...