redux是一个数据状态管理的js框架,redux把行为抽象成一个对象,把状态抽象成一个很大的数据结构,每次用户或者其他什么方式需要改变页面都可以理解成对数据状态的改变,根据出发这次改变的不同从而有各式各样的action(行为),如何根据action(行为)来改变状态呢?这时候就需要一个reduce,reduce必须是一个纯函数,reduce是一个定义行为如何改变状态的逻辑处理的函数,action传入通过reduce的逻辑改变状态,最后状态发生改变,发出订阅消息,触发监听函数的执行。思路很简单,看文档也很容易上手,代码量也不大。

但是最近使用redux发现一个问题,如果同时触发多个action的话,会频繁触发监听函数的执行,比如如下代码

(function(){
dispatch(action1);
dispatch(action2)
})(dispatch)

  会触发2次监听函数,一般监听函数回去修改视图,但其实处理完这两次action,在去触发监听函数,用户看到的效果是一样的,不会看到触发第一次action和第二次action之间的过渡,但是如果能一次性把状态跟新完,在触发一次监听函数,那样的话会避免执行一些没必要的代码,例如代码如下:

(function(){
dispatch(action1,action2); })(dispatch)

  但是阅读了redux源码发现,dispatch函数只能接受一个参数,源码如下:

function dispatch(action) {
if (!isPlainObject(action)) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
} if (typeof action.type === 'undefined') {
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
} if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
} try {
isDispatching = true
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
} const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
} return action
}

  当然了如果修改源码的会有很多种思路,第一种就是监听还是放到事件队列的尾部执行,如下代码:

var nextTick=(function(){
let promise = new Promise(function (resolve,rej){
resolve()
})
return function (fn){
promise.then(fn)
}
})() nextTick(listen)

  这样方式的话,也许会出现队列非常多的话会延迟跟新试图,对用户不友好,最后我采用了最后一个办法,让dispatch函数可以一次处理多个action:

function dispatch(...actions) {

    if (actions.some((action, index, arr) => {
return !isPlainObject(action)
})) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
} // if (!isPlainObject(action)) {
// throw new Error(
// 'Actions must be plain objects. ' +
// 'Use custom middleware for async actions.'
// )
// }
if (actions.some((action, index, arr) => {
return typeof action.type === 'undefined'
})) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
} // if (typeof action.type === 'undefined') {
// throw new Error(
// 'Actions may not have an undefined "type" property. ' +
// 'Have you misspelled a constant?'
// )
// } if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
} try {
isDispatching = true
currentState = actions.reduce(currentReducer, currentState)
// currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
} const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
} return actions
}

  

记一次修改框架源码的经历,修改redux使得redux 可以一次处理多个action,并且只发出一次订阅消息的更多相关文章

  1. ABP框架源码学习之修改默认数据库表前缀或表名称

    ABP框架源码学习之修改默认数据库表前缀或表名称 1,源码 namespace Abp.Zero.EntityFramework { /// <summary> /// Extension ...

  2. 修改elementUI源码新增组件/修改组件

    前言 经常我们会遇到elementUI组件库期间有5%达不到我们想要的需求,第一我们重新写组件,第二我们改源码 安装element https://github.com/ElemeFE/element ...

  3. YII框架源码分析(百度PHP大牛创作-原版-无广告无水印)

           YII 框架源码分析    百度联盟事业部——黄银锋 目 录 1. 引言 3 1.1.Yii 简介 3 1.2.本文内容与结构 3 2.组件化与模块化 4 2.1.框架加载和运行流程 4 ...

  4. TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端

    目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP部分的使用 框架源码结构 补充说明 源码地址 说明 之前有好几篇博客在讲TCP/UDP通信方 ...

  5. CI框架源码阅读笔记3 全局函数Common.php

    从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...

  6. CI框架源码阅读笔记2 一切的入口 index.php

    上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...

  7. Android Small插件化框架源码分析

    Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github ...

  8. iOS学习——布局利器Masonry框架源码深度剖析

    iOS开发过程中很大一部分内容就是界面布局和跳转,iOS的布局方式也经历了 显式坐标定位方式 --> autoresizingMask --> iOS 6.0推出的自动布局(Auto La ...

  9. 【java集合框架源码剖析系列】java源码剖析之ArrayList

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 本博客将从源码角度带领大家学习关于ArrayList的知识. 一ArrayList类的定义: public class Arr ...

随机推荐

  1. laravel7 图片上传及视图显示

    1:修改框架config下的文件filesystems.php中的配置: 原文件 <?php return [ /* |------------------------------------- ...

  2. SQLserver建表规则

    --执行环境:生产环境 / beta环境--备注:文件开头写上描述或者原因.项目USE database --例如 USE LZB GO CREATE TABLE Ymtable1 ( iOrderI ...

  3. Docker 学习之命令篇

      Docker 学习之命令篇 1. docker images //镜像列表 2. docker ps –a //所有运行过的容器 3. docker ps –l 最后运行的容器 4. docker ...

  4. ssh-ssl编译安装

    升级前准备 #下载所需依赖包#yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel pcre-devel pam-d ...

  5. CVE-2017-8759 微软word漏洞复现以及利用

    CVE-2017-8759 微软word漏洞复现以及利用 0x00 漏洞描述 近日,360集团核心安全事业部分析团队发现一个新型的Office文档高级威胁攻击,攻击使用了9月12日补丁刚修复的.NET ...

  6. 先知xss挑战赛学习笔记

    xss游戏 游戏地址:http://ec2-13-58-146-2.us-east-2.compute.amazonaws.com/ LEMON参考wp地址 1. 文件上传 源码如下 <?php ...

  7. [转载]Linux后门整理合集(脉搏推荐)

    我在思考要不要联系下....都禁止转载了.... 简介 利用 Unix/Linux 自带的 Bash 和 Crond 实现远控功能,保持反弹上线到公网机器. 利用方法 先创建 /etc/xxxx 脚本 ...

  8. 解决centos7服务器shadows已启动但是无法连接的问题

    firewall-cmd --permanent --add-port=8989/tcp firewall-cmd --reload 这是由于centos7防火墙并没有开放ss端口的问题 添加json ...

  9. xx局点FusionCloud6.3 type1 计算配额失败问题

    现象: 排查过程: 1.登录云平台部署面,选择部署资源-服务器 2.找到MOC-ManageOne-Service01.MOC-ManageOne-Service02两台机器ip地址. 3.用ssh工 ...

  10. Joplin开源笔记软件使用入门

    Joplin是一款开源免费的笔记软件,可以记录笔记.待办清单,支持Markdown,可导出Markdown格式.HTML格式.PDF格式的文档,具备自动同步功能,可定时自动备份到文件系统或网盘. Jo ...