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

Redux中间件的原理

原创
作者头像
挥刀北上
修改2021-01-22 11:03:33
4630
修改2021-01-22 11:03:33
举报
文章被收录于专栏:Node.js开发Node.js开发

先看一张图:

redux的中间件原理
redux的中间件原理

我们在react中使用redux时有时候需要使用redux的中间件,那么redux的中间件是如何是实现的呢?看代码:

let store = {
  dispatch(action) {
    console.log(action);
  }
}

let fn1 = function (store) {
  return function (next) {
    console.log("fn1 next start")
    return function (action) {
      console.log("fn1 start")
      let result = next(action)
      console.log("fn1 end")
      return result;
    }
  }
}

let fn2 = function (store) {
  return function (next) {
    console.log("fn2 next start")
    return function (action) {
      console.log("fn2 start")
      let result = next(action)
      console.log("fn2 end")
      return result;
    }
  }
}
let fn3 = function (store) {
  return function (next) {
    console.log("fn3 next start")
    return function (action) {
      console.log("fn3 start")
      let result = next(action)
      console.log("fn3 end")
      return result;
    }
  }
}

let arrs = [fn1, fn2, fn3];

function applymid(store, arrs){

  let dispatch = store.dispatch;
  arrs.forEach(element => {
    dispatch= element(store)(dispatch)
  });
  return Object.assign({},store,{dispatch});

}


// 循环过程中 第一次执行element(store)(dispatch);得到的结果是
dispatch1 = function (action) {
  console.log("fn1 start")
  let result = next(action)   //此处next为原始最初的dispatch
  console.log("fn1 end")
  return result;
}
// 循环第二次执行element(store)(dispatch);得到的结果是:

dispatch2 = function (action) {
  console.log("fn2 start")
  let result = next(action) //此处next为原始最初的dispatch1
  console.log("fn2 end")
  return result;
}

// 此时的next就是上一次的dispatch 即dispatch1代入得到:

dispatch = function (action) {
  console.log("fn2 start")
  let result = (function (action) {
    console.log("fn1 start")
    let result = next(action)   //此处next为原始最初的dispatch
    console.log("fn1 end")
    return result;
  })(action);
  console.log("fn2 end")
  return result;
}

// 简化:

dispatch = function (action) {
  console.log("fn2 start")
  console.log("fn1 start")
  let result = next(action)   //此处next为原始最初的dispatch
  console.log("fn1 end")
  console.log("fn2 end")

}

let s = applymid(store,arrs);

s.dispatch(999);

首先我们要用一句话来概括redux中间件的原理,那就是store要执行dispatch时,要按照中间件的顺序执行中间件,最后再执行dispatch,逻辑图就像一个洋葱。

如何实现呢?这里面遵循几条原则,首先中间件的定义方式,一个中间件涉及三个函数,a函数返回b函数,b函数返回c函数,中间件函数本质可以连续调用执行 中间件函数(store)(next)(action)。

中间件函数连续调用两次返回的函数就是新版的dispatch,即dispatch = 中间件函数(store)(next);

dispatch = 中间件函数(store)(dispatch);是中间状态,一开始的dispatch等于store.dispatch,也是最原始的dispatch,代码中多次执行dispatch = 中间件函数(store)(dispatch),多次对dispatch进行包装并对dispatch进行赋值,等号右侧对dispatch进行包装,后者说是修饰,类似修饰符,修饰完成后重新赋值个dispatch,这样dispatch就是更新完的dispatch了。

applyMiddleware的本质就两点,遍历中间件,用中间件修饰dispatch,重新给dispatch赋值,遍历完成后得到新的dispatch返回新的dispatch。

这种代码结构比较有意思,需要反复揣摩才能熟练掌握,希望对你有所帮助。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

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