RxJS + Redux + React = Amazing!(译一)
今天,我将Youtube上的《RxJS + Redux + React = Amazing!》翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频:
https://www.youtube.com/watch?v=AslncyG8whg
开场白
管理状态很困难,对吧?如果你写过复杂应用,你一定对此深恶痛绝。React社区还有Angular2社区和Ember社区现在都开始使用一个库,叫Redux。为什么?因为它让管理状态变得简单多了。但Redux有个问题,就是它对你写异步代码没什么帮助,因为Redux认为异步是个比管理状态更难的问题。特别是当你试图去解决一些复杂问题,比如:并行或多重WebSockets。这些问题本身就很复杂,你也没辙。所以,这次演说将会介绍使用另一个库,叫RxJS。这个库至少可以让异步问题变得可控可管理,至少可以让你知道发生了什么。

自我介绍
我是谁?我是Jay Phelps。很明显,照片中的衬衫不是我今天穿的,尽管它们很像,(歪果仁就是啰嗦,不过场下听众听到这都乐了)。其实我穿了另外一件蓝色衬衫,但这是我的推特头像,它可以帮助那些还没有认出我的人认出我来。很明显,我是Netflix的软件工程师。你可以关注我,通过下划线jayphelps(就是_jayphelps,然后他又扯了一些没用的,说有另外一个jayphelps,是一个16岁的家伙,经常转推一些足球图片。他说他经常说这个梗,因为很多本来要关注他的人,都去关注那个16岁足球小哥了)。

什么是Redux
让我们开始讨论什么是Redux。这个演说不会详细介绍Redux和RxJS,因为它们本身就有非常多相关的演说,但我会给你们一个速成教程。这样,即便你不知道它们具体是什么,至少可以了解个大概。Redux提供了一个可预测的状态管理,它通过action和reducer来完成这个工作。那么什么是action?action被用来描述发生的事,但它不关心如何这件事如何发生。让我们来看个例子吧!
{
type: "CREATE_TODO",
payload: "Build my first redux app"
}
这是个简单的action,通过这个action,你知道了你要去创建一个todo,这个todo的内容是什么,但它没说如何去创建这个todo,它没说是是否要与服务器交互,也没说是否要存到数据库或localstorage中,它没有进行异步操作,它是个完全可以被序列化的对象。那么什么是reducer?reducer是一些纯函数,这意味着每次你给了一样的输入,那么就会有一样的输出,没有副作用。reducer的具体功能是输入上个的state和action,然后输出新的state,当然新的state可以和上个state完全一样(就是case为default的情况)。举个非真实场景的例子吧,这是个计数器的例子:
export default function counter(state = 0, action) {
switch (action.type) {
case INCREMENT_COUNTER:
return state + 1
case DECREMENT_COUNTER:
return state - 1
default:
return state
}
}
我们仅仅就是选择action类型,当action是加一,state就加一,action是减一,state就减一,就是这么字面性质的工作。reducer负责state更新,但它必须是同步的。这意味着,如果reducer收到加一的action,那么就必须立马加一。reducer不能去除速率过快的事件(debounce),也不能和服务器交互,也不能问“我是否可以加一“。reducer只能受到action,然后立马同步执行。

异步
我们平时都做些什么类型的异步操作呢?(竟然没有衔接,直接从Redux转折到异步)为何说异步是个难缠的问题呢?常见的异步事件操作包括:
- 用户交互(键盘、鼠标)
- Ajax(这就像面包和黄油一样熟悉,我们每个人都会做Ajax请求)
- 计时器/动画
- Web Sockets
- Web Workers
这不是个详细的列表。上述其中一些可以同步处理,尽管它们本身是异步的。React与Redux已经封装好了,你可以直接同步处理它们!(然后,他举了一个例子,React组件的点击事件,可以触发加一的action,然后reducer处理这个action)从技术角度上来说,这些事件是异步的,但你可以用同步的方式来处理它。为什么?因为React已经帮你处理了异步。但是,问题来了,如果你还想要点击,如果你想去除速率过快的事件,比如,用户点了很多次,而你不想每次都进行事件处理。这时,你通常会计算点击间隔,然后只处理间隔较大的点击事件。有时候,你需要像这样的更多的控制。这些控制包括:
- Ajax取消/组合(组合的意思是,比如你发起了一个Ajax,然后你又发起了另外一个Ajax,后一个的发起用到了前一个的响应数据)
- Debounce/throttle/buffer等这些与时间相关的操作
- Drag and Drop
- Web Sockets, Web Workers, etc
在Redux世界里,人们经常使用中间件来处理这些操作。所有action在你发起后,和到达reducer前,都必须穿过中间件。现在已经有很多中间件使用回调和Promise来做这些事了(指那些复杂的异步操作)。下面就让我们看看这两种最常用的异步处理方法吧!

回调和Promise
回调对大家来说非常熟悉,因为它是JavaScript最原始的处理异步的方式(然后他举了个回调的例子,回调太简单,不再赘述)。但是回调有很多问题,其中最常见的就是“回调地狱“。大家几乎都见过这种代码(他指着屏幕上的代码示例)。如果你想改变代码,比如做点这样的事:
- 条件判断,然后决定是否进行下一个异步
- 你不想顺序执行这些异步
- 更加复杂的回调操作,比如你想并发它们等
那么事情就变得非常复杂了,对吧?我的同事称回调地狱是“V型电吉他“,因为它们的形状非常相似。不过,有了一种解决方案,叫Promise。使用Promise有个绝招,那就是如果你给Promise提供了一个回调,这个回调也返回了一个Promise,那么你可以将其写为平行的风格(这算什么绝招啊,大多数人都知道吧!)。如果你理解了这种模式,那么Promise的代码将会变得非常易读。这很棒,它是个非常好的候选方案。让我们更深入的了解一下Promise吧!Promise拥有这些特性:
- 被保证的未来(意思是,一旦你创建了一个Promise,那么它肯定会执行它要做的事情,你不能停止它,开始黑Promise了。)
- 不可变
- 单一的值(意思是,如果你监听一个Promise很多次,你只会得到相同的值,而不是执行多次请求 )
- 缓存
在真实项目中,你会发现“被保证的未来“和“单一的值“是个问题,先说“被保证的未来“吧,Promise是不能被取消的。或许你会问,我既然创建了一个Promise,为何要取消它?以下场景,你就要取消你的Promise,也就是异步请求:
- 改变路由/视图(他举了Netflix的一个例子,大概就是点进一个页面,然后后悔了就返回了,这时需要取消请求)
- 自动补全(这个例子比较常见,自动补全总不能每次键盘按下都发请求吧?)
- 用户非要你取消
可见,取消异步是一个非常常用,但是容易被忽略的需求。再说Promise的“单一的值“吧!(然后开始黑Promise的“单一的值“,不过他欲扬先抑了一下),其实绝大多数场景下,我们只需要单一的值,比如Ajax,请求-响应,就是单一的值。但人们不只想做这些事,像之前提到的:
- 用户交互(键盘、鼠标)
- Ajax(这就像面包和黄油一样熟悉,我们每个人都会做Ajax请求)
- 计时器/动画
- Web Sockets
- Web Workers
上述场景也就Ajax是单一的值,其他几个场景都不是。那我们该怎么办呢?那就是使用Observable!

未完待续
这个视频太长了,今天就到此为止吧!在这篇文章中,我们主要听了Jay Phelps:
- 讲了Redux和异步
- 黑了回调和Promise
下篇文章我们将听他:
- 吹Observable的牛
- 讲述他和他搭档造redux-obserable这个轮子背后的故事!
第二篇已经发布:RxJS + Redux + React = Amazing!(译二)
RxJS + Redux + React = Amazing!(译一)的更多相关文章
- RxJS + Redux + React = Amazing!(译二)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...
- Redux & React & react-redux
Redux Redux & React & react-redux https://redux.js.org/ https://redux.js.org/api https://red ...
- Redux React & Online Video Tutorials
Redux React & Online Video Tutorials https://scrimba.com/@xgqfrms https://scrimba.com/c/cEwvKNud ...
- [Redux] React Todo List Example (Toggling a Todo)
/** * A reducer for a single todo * @param state * @param action * @returns {*} */ const todo = ( st ...
- [Redux] React Todo List Example (Adding a Todo)
Learn how to create a React todo list application using the reducers we wrote before. /** * A reduce ...
- [Redux] React Todo List Example (Filtering Todos)
/** * A reducer for a single todo * @param state * @param action * @returns {*} */ const todo = ( st ...
- Flux --> Redux --> Redux React 入门
本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...
- Flux --> Redux --> Redux React 基础实例教程
本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...
- Flux --> Redux --> Redux React 入门 基础实例使用
本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...
随机推荐
- word-wrap ,word-break 和white-space 的联系
在工作中我遇到一个问题,其实功能也不复杂,就是上面有个textarea标签 ,里面输入内容,下面有个显示效果 ,有个条件就是 上面输入的什么格式(比如换行等等),下面显示的也是 什么格式.如下图: 这 ...
- .NetCore MVC中的路由(2)在路由中使用约束
p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
- Kooboo CMS技术文档之一:Kooboo CMS技术背景
语言平台 依赖注入方案 存储模型 1. 语言平台 Kooboo CMS基于.NET Framework 4.x,.NET Framework 4.x的一些技术特性成为站点开发人员使用Kooboo CM ...
- 由js apply与call方法想到的js数据类型(原始类型和引用类型)
原文地址:由js apply与call方法想到的js数据类型(原始类型和引用类型) js的call方法与apply方法的区别在于第二个参数的不同,他们都有2个参数,第一个为对象(即需要用对象a继承b, ...
- C#委托异步调用
参考页面: http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-get.html http://www.yuanjiaocheng.net/w ...
- Syscall,API,ABI
系统调用(Syscall):Linux2.6之前是使用int0x80(中断)来实现系统调用的,在2.6之后的内核是使用sysentry/sysexit(32位机器)指令来实现的系统调用,这两条指令是C ...
- Nexus(一)环境搭建
昨天,成功搭建了自己的 Maven 环境(详见:Maven(一)环境搭建),今天就来研究和探讨下 Nexus 的搭建! 使用背景: 安装环境:Windows 10 -64位 JDK版本:1.7 Mav ...
- git快速get
配置:git config --global user.name 'yangshaoxiang' git config --global user.email '254135495@qq.com' s ...
- Aop动态生成代理类时支持带参数构造函数
一.背景 在某些情况下,我们需要植入AOP代码的类并没有默认构造函数.那么此时动态生成的代理类也需要相同签名的构造函数,并且内部调用原始类的构造函数.自己折腾了1晚上没搞定,现在搞定了发出来供大家一起 ...