Redux thunk中间件
redux-thunk
https://github.com/reduxjs/redux-thunk
Why Do I Need This?
Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.
Motivation
Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods
dispatch
andgetState
as parameters.
相对于同步action, 修改state场景, 对于异步场景, 或者 复杂的同步场景, 就需要thunk中间件。
thunk中间件允许actionCreator返回的dispatch的对象, 不再试普通对象的action(包括type 和 payload参数),
而是一个函数,函数入参为 dispatch 和 getState , 在此函数中处理异步调用 或者 复杂条件的 处理。
异步请求的例子:
const INCREMENT_COUNTER = 'INCREMENT_COUNTER'; function increment() {
return {
type: INCREMENT_COUNTER
};
} function incrementAsync() {
return dispatch => {
setTimeout(() => {
// Yay! Can invoke sync or async actions with `dispatch`
dispatch(increment());
}, 1000);
};
}
条件dispatch例子:
function incrementIfOdd() {
return (dispatch, getState) => {
const { counter } = getState(); if (counter % 2 === 0) {
return;
} dispatch(increment());
};
}
给store添加thunk中间件
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index'; // Note: this API requires redux@>=3.1.0
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
dispatch a thunk action:
function fetchSecretSauce() {
return fetch('https://www.google.com/search?q=secret+sauce');
} function makeASandwichWithSecretSauce(forPerson) { // Invert control!
// Return a function that accepts `dispatch` so we can dispatch later.
// Thunk middleware knows how to turn thunk async actions into actions. return function (dispatch) {
return fetchSecretSauce().then(
sauce => dispatch(makeASandwich(forPerson, sauce)),
error => dispatch(apologize('The Sandwich Shop', forPerson, error))
);
};
} // Thunk middleware lets me dispatch thunk async actions
// as if they were actions! store.dispatch(
makeASandwichWithSecretSauce('Me')
);
dispatch返回结果实际上是一个promise,可以使用 then语句观察结果:
// It even takes care to return the thunk’s return value
// from the dispatch, so I can chain Promises as long as I return them. store.dispatch(
makeASandwichWithSecretSauce('My partner')
).then(() => {
console.log('Done!');
});
什么是thunk?
https://github.com/reduxjs/redux-thunk
thunk就是一个函数包裹了一个表达式, 表达式延迟执行。
What’s a thunk?!
A thunk is a function that wraps an expression to delay its evaluation.
// calculation of 1 + 2 is immediate
// x === 3
let x = 1 + 2; // calculation of 1 + 2 is delayed
// foo can be called later to perform the calculation
// foo is a thunk!
let foo = () => 1 + 2;The term originated as a humorous past-tense version of "think".
https://en.wikipedia.org/wiki/Thunk#cite_note-1
一段程序,不立刻执行, 而是在真正使用的地方, 才计算其值。
相关术语:
call by name
lazy evaluation
表现形式为, 使用匿名函数封装, 等待调用执行任务。
In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine. It can simply be thought of as a function that takes no arguments, waiting to be called upon to do its work. They have a variety of other applications in compiler code generation and modular programming.
如下面的例子: hypot(3, 4)语句计算比较耗时,将其封装为匿名函数, 在使用的地方调用匿名函数,就相当于执行hypot(3, 4)。
// 'hypot' is a function that returns another function which is already closed over all required data
const hypot = (x, y) => () => Math.sqrt(x * x + y * y);
// 'thunk' is a function that takes no arguments and performs a potentially expensive operation (computing a square root, in this example) and/or causes some side-effect to occur
const thunk = () => hypot(3, 4); // the thunk can then be passed around...
doSomethingWithThunk(thunk);
// ...or evaluated
thunk(); // === 5
如下wiki描述, thunk为最早使用在ada语言的执行上, 当其执行时候, 对于函数参数的类型, 其实可以在编译的时候通过一些思考(thought)确定, 这个确定的过程, 被称为thunk。
增加编译时候的一点点小时间, 从而提高解释时候的效率, 减少时间, 这个类型推断的过程, 如果在执行阶段执行, 那么会被多次执行; 如果每次执行都是一样结果, 那么完全没有必要多次执行,
在编译时候确定(thought), 或者在过程的第一次执行后确定(thought),进而被缓存起来,可以被多次使用。
这种过程的形式被固化下来,并被推广到其它应用场景, 并被命名为thunk。
Eric Raymond rejects "a couple of onomatopoeic myths circulating about the origin of this term" and cites the inventors of the thunk recalling that the term "was coined after they realized (in the wee hours after hours of discussion) that the type of an argument in Algol-60 could be figured out in advance with a little compile-time thought [...] In other words, it had 'already been thought of'; thus it was christened a thunk, which is 'the past tense of "think" at two in the morning'. See: Raymond, Eric S. (1996). Raymond, Eric S., ed. The New Hacker's Dictionary. MIT Press. p. 445. ISBN 9780262680929. Retrieved 2015-05-25.
http://www.ruanyifeng.com/blog/2015/05/thunk.html
编译器的"传名调用"实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数。
function f(m){
return m * 2;
} f(x + 5); // 等同于 var thunk = function () {
return x + 5;
}; function f(thunk){
return thunk() * 2;
}
上面代码中,函数 f 的参数 x + 5 被一个函数替换了。凡是用到原参数的地方,对 Thunk 函数求值即可。
这就是 Thunk 函数的定义,它是"传名调用"的一种实现策略,用来替换某个表达式。
为什么要使用redux-thunk?
如下图,阮老师的文章描述, redux框架,将应用分为 action reducer view三个部分,
对于异步获取数据, 或者添加条件过滤数据场景, 这个过程,在view(react.componet)中实现是不合适, 因为其只负责视图展示,
放在reducer中不行了, 因为框架规定reducer只能作为纯函数使用,
这个重任只能交给 action, 实现 thunk action来做中间层逻辑,此逻辑对数据获取和数据更新到状态负责, 术语 redux store的数据管理和维护的范围。
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html
Action 发出以后,过一段时间再执行 Reducer,这就是异步。
怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。
Redux thunk中间件的更多相关文章
- Redux的中间件原理分析
redux的中间件对于使用过redux的各位都不会感到陌生,通过应用上我们需要的所有要应用在redux流程上的中间件,我们可以加强dispatch的功能.最近也有一些初学者同时和实习生在询问中间件有关 ...
- Redux 和 Redux thunk 理解
1: state 就像 model { todos: [{ text: 'Eat food', completed: true }, { text: 'Exercise', completed: fa ...
- Redux的中间件Middleware不难,我信了^_^
Redux的action和reducer已经足够复杂了,现在还需要理解Redux的中间件.为什么Redux的存在有何意义?为什么Redux的中间件有这么多层的函数返回?Redux的中间件究竟是如何工作 ...
- 17. react redux的中间件
1. redux 数据流程图 View 会派发一个 Action Action 通过 Dispatch 方法派发给 Store Store 接收到 Action 连同之前的 State 发给 Red ...
- redux进阶 --- 中间件和异步操作
你为什么需要异步操作? https://stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-async-flow-in ...
- 理解 Redux 的中间件
将该思想抽象出来,其实和 Redux 就无关了.问题变成,怎样实现在截获函数的执行,以在其执行前后添加自己的逻辑. 为了演示,我们准备如下的示例代码来模拟 Redux dispatch action ...
- React:快速上手(7)——使用中间件实现异步操作
React:快速上手(7)——使用中间件实现异步操作 本文参考链接:Stack Overflow redux-thunk 我们使用store.dispath进行派发时,只能传递一个普通对象进去,如下: ...
- Redux异步解决方案之Redux-Thunk原理及源码解析
前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...
- Redux和React-Redux的实现(三):中间件的原理和applyMiddleware、Thunk的实现
现在我们的Redux和React-Redux已经基本实现了,在Redux中,触发一个action,reducer立即就能算出相应的state,如果我要过一会才让reducer计算state呢怎么办?也 ...
随机推荐
- 从0开始的Python学习011模块
简介 你已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个包含了所有你定义的函数和变量的 ...
- Cannot read property 'validate' of undefined
在使用element-UI表单验证中一直报错,'Error in event handler for “click”: “TypeError: Cannot read property ‘valida ...
- java 根据ip获取地区信息(淘宝和新浪)
package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr ...
- 网络流之最小费用最大流 P1251 餐巾计划问题
题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送 ...
- python从开始到放弃想标题的day12
上次有说道函数的返回值,但是不是所有的数据类型都有返回值,一些常用的比如str基本都有返回值,list基本都没有返回值,dict基本都有返回值,还有就是函数和函数之间的数据是互不影响的,哪怕是一个函数 ...
- PyCharm选中文件夹新建时Directory与Python package的区别
pycharm创建普通的directory和package时都是在硬盘上建立一个文件夹.但是建package时会在这个文件夹中自动地生成一个空的__init__.py文件.python的一个包是一个带 ...
- PHP开发高可用高安全App后端
基于thinkphp5开发的APP,涵盖阿里大于,七牛云图片上传,RestfulApi,短信验证, 需要联系我:QQ:1844912514
- PHP 面试知识点整理归纳
基础篇了解大部分数组处理函数 array_chunk — 将一个数组分割成多个 array_column — 返回数组中指定的一列 array_combine — 创建一个数组,用一个数组 ...
- python nympy 序列化dict
首先定义dict dict={} 对象写到dict dict['key']=object 存储dict np.save('dictname.npy',dict) 读取dict dictname=np. ...
- maven:私服的相关配置
添加到settings.xml中 <server> <id>releases</id> <username>admin</username> ...