前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redux-thunk中间件

redux-thunk中间件

作者头像
张宗伟 plus
发布2022-10-28 13:36:02
5250
发布2022-10-28 13:36:02
举报
文章被收录于专栏:张宗伟 plus张宗伟 plus

最近在看redux,主要是redux官方教程(参考文章1)和网上文章(参考文章2),基础部分已经看完,正在理解middleware中间件部分,自我感觉中间件的思想不难理解,主要是它的实现方式涉及到函数式编程,真的太抽象了。redux-thunk是一种中间件,它能使你在action creator中返回函数,此返回函数就是thunk函数,模拟一下就是

代码语言:javascript
复制
// thunk函数
(dispatch,getState,extraCustomArgument) => {...}

它接收三个参数,dispatch用于触发actiongetState用于获取stateextraCustomArgument用于自定义参数。同样此thunk函数可以被dispatch,并且thunk函数的返回值也是dispatch的返回值,另外在action creator中也可以dispatch其他的thunk函数。redux-thunk的作用大致就是上面总结的,此文章也只是将官网readme给翻译一下(参考文章3)。

redux-thunk解决了什么问题


在基本的redux中,只能dispatch同步的action来更新state,那么对于dispatch异步的action来更新state呢?就要使用中间件了,而redux-thunk就是这样一个中间件。

具体的改变


  • 之前action creator返回的是action对象,现在可以返回一个thunk函数,这个函数可以执行一些副作用,不再需要保持它的纯净。它可以异步或者在某一条件满足时dispatch action,代码如下:
代码语言:javascript
复制
const INCREMENT_COUNTER = 'INCREMENT_COUNTER'
// 普通的action creator
function increment() {
  return {
      type: INCREMENT_COUNTER
    }
}
// 返回thunk函数的action creator,这个是延迟(异步)执行
function incrementAsync() {
  // 可以看出其中使用了 setTimeout,即执行了副作用
  return (dispatch) => {
    setTimeout(() => {dispatch(increment())},1000)
  }
}
// 返回thunk函数的action creator,这个是满足一定条件执行
function incrementIfOdd() {
  return (dispatch,getState) => {
    const {counter} = getState()
    if (counter % 2 === 0) {
      // 终止,什么也不做
      return
    }
    dispatch(increment())
  }
}

thunk是什么


thunk是一个函数,它封装一个表达式,使得表达式可以延时计算。

代码语言:javascript
复制
// thunk函数
function thunk() {
  return 1+2
}
// 当你call时,才能得到 1+2 的值
thunk() // 3

此函数其实早就有了,之前是用于“传名调用”的一种实现策略,用来替换某个表达式。

代码语言:javascript
复制
// 对于函数参数的求值,有两种方式:
// 1. 传值调用:即在参数传入函数体之前,就进行求值,
//    这种方式可能在函数体不需要此参数时,造成浪费
// 2. 传名调用:即在函数体内用到时,才进行求值,可以体会一下下面的例子
// 传名调用
function f(x) {
  return x*2
}
f(3+2)
// 等同于
// thunk函数
function thunk() {
  return 3+2
}
function f(thunk) {
  return thunk()*2
}

对于JavaScript来说,thunk具有另一种含义,用于将多参数函数转换成单参数函数,且只接受callback作为参数。

代码语言:javascript
复制
// 正常版本的readFile函数
fs.readFile(fileName,callback)
// 经过thunk改变后
const thunkReadFile = thunk(fileName)
const result = thunkReadFile(callback)
// thunk的过程
const thunk = (fileName) => (callback) => fs.readFile(fileName,callback)

那么对于有callback的函数来说,都可以进行thunk化,写一个thunk函数转换器。

代码语言:javascript
复制
// thunk函数转换器
const thunkTrans = (fn) = > () => {
  // 将arguments类数组转换为数组,其实不一定要转换,使用(...)也可
  const args = Array.prototype.slice.call(arguments)
  return (callback) => {
    args.push(callback)
    return fn.apply(this,args)
  }
}
// 有时候真的感叹js的函数真是太神奇了,不,是js执行机制太神奇了!
// 使用的时候比上面多一步
const createThunkReadFile = thunkTrans(fs.readFile)
const thunkReadFile = createThunkReadFile(fileName)
const result = thunkReadFile(callback)

以上都是参考阮一峰老师的文章(参考文章4)。

复杂用法


就是说在action creator中还可以dispatch其他的action creator,不论是返回action对象还是返回一个函数。这对于操作异步流来说真是太方便了,想一想.then().then(). . .

另一个就是传入extraCustomArgument参数。这一部分请直接参考redux-thunk官方文档。

可以看出,redux-thunk就是一个扩展功能的中间件,它的源代码实现非常少!之后估计也要学习一下,到时再写一篇文章。

参考文章

  1. http://cn.redux.js.org/
  2. https://github.com/brickspert/blog/issues/22
  3. https://github.com/reduxjs/redux-thunk
  4. http://www.ruanyifeng.com/blog/2015/05/thunk.html
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 张宗伟 plus 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档