RxJS 6有哪些新变化?
我们的前端工程由Angular4升级到Angular6,rxjs也要升级到rxjs6. rxjs6的语法做了很大的改动,幸亏引入了rxjs-compact包,否则升级工作会无法按时完成。
按照官方的建议,逐步将原rxjs语法改为rxjs6后,要去掉rxjs-compact包。 rxjs-compact包无法转换一些语法,我们的工程中没用到这些特性,原rxjs代码可以转为rxjs6.
原文链接:https://segmentfault.com/a/1190000014956260
RxJs 6于2018年4月24日正式发布,为开发人员带来了一些令人兴奋的增补和改进。Ben Lesh, rxJS核心开发成员,强调:
- RxJS 6在拥有更小API的同时,带来了更整洁的引入方式
- 提供一个npm包,该package可以处理RxJS的向后兼容性,使得开发人员可以在不更改代码的情况下进行更新,同时还可以帮助TypeScript代码自动迁移。
RxJs 6这些新的改动为开发人员提供了以下三方面的优化:模块化方面的改进、性能提升、调试更方便。RxJs团队尽力保持新版本的向后兼容性,但是为了减少RxJs的API数量,还是引入了一些重大修改。
下面让我们一起来看一下RxJs团队在新版本中引入了哪些修改。
RxJS 6的向后兼容性
为了便捷地从RxJS 5迁移到RxJS 6,RxJS团队发布了一个名为rxjs-compa
t的兄弟软件包。该软件包在v6
和v5
的API之间创建了一个兼容层。
RxJs团队建议开发人员通过安装^6.0.0
版本的rxjs
和rxjs-compat
包来升级现有应用:
npm install rxjs@6 rxjs-compat@6 --save
此包允许您在升级RxJS 6的同时继续运行现有代码库,而不会出现问题。他支持在RxJs 6中移除掉的功能。
安装rxjs-compat
会导致打包后代码包体积的增加,如果你使用的是4.0.0版本以下的Webpack,该影响会被放大。
因此建议升级完成后将rxjs-compat
移除。
使用rxjs-compat升级RxJS的限制
只有两个重大修改在rxjs-compat
中未覆盖:
TypeScript原型操作符
在极少数情况下,您的代码库定义了它自己的TypeScript原型操作符并修改了Observable
命名空间。该情况下,您需要更新你的操作符相关代码才能使TypeScript正常编译。
在版本发布说明中,用户自定义的原型操作符可按如下方式创建:
Observable.prototype.userDefined = () => {
return new Observable((subscriber) => {
this.subscribe({
next(value) { subscriber.next(value); },
error(err) { subscriber.error(err); },
complete() { subscriber.complete(); },
});
});
});
source$.userDefined().subscribe();
为编译该类型的自定义操作符,需要做如下修改:
const userDefined = <T>() => (source: Observable<T>) => new Observable<T>((subscriber) => {
this.subscribe({
next(value) { subscriber.next(value); },
error(err) { subscriber.error(err); },
complete() { subscriber.complete(); },
});
});
});
source$.pipe(
userDefined(),
)
同步错误处理
不再支持在try / catch
块内调用Observable.subscribe()
。使用用Observable.subscribe()
方法中的错误回调方法替换原先的try / catch
块来完成的异步错误的处理。
示例如下:
// deprecated
try {
source$.subscribe(nextFn, undefined, completeFn);
} catch (err) {
handleError(err);
}
// use instead
source$.subscribe(nextFn, handleError, completeFn);
现在在Observable.subscribe()
中必须定义一个错误回调方法来异步处理错误。
删除RxJs兼容层前需要做的修改
如上所诉,rxjs-compat
提供了V5
与v6
API间的临时兼容层,实质上rxjs-compat
为您的代码库提供了所需的v5
版本功能,使得您可以逐步将您的代码库升级到v6版本。为了完成升级并移除rxjs-compat
依赖,您的代码库需要重构并停止使用v5
版本中的如下功能:
修改import
路径
建议TypeScript开发人员使用rxjs-tslint
来重构import
路径。
RxJS团队设计了以下规则来帮助JavaScript开发人员重构import
路径:
rxjs
: 包含创建方法,类型,调度程序和工具库。import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent } from'rxjs';
rxjs/operators
: 包含所有的管道操作符import { map, filter, scan } from 'rxjs/operators';
rxjs/webSocket
: 包含websocket subject实现.import { webSocket } from 'rxjs/webSocket';
rxjs/ajax
: 包含Rx ajax实现.import { ajax } from 'rxjs/ajax';
rxjs/testing
: 包含RxJS的测试工具库.import { TestScheduler } from 'rxjs/testing';
使用管道操作而不是链式操作
使用新的管道操作符语法替换旧有的链式操作。上一个操作符方法的结果会被传递到下一个操作符方法中。
不要移除rxjs-compat
包,直到你将所有的链式操作修改为管道操作符。如果您使用TypeScript,ts-lint
会在某种程度上自动执行此项重构。
Ben Lesh在ng-conf 2018上解释了为什么我们应该使用管道操作符。请按照如下步骤将您的链式操作替换为管道操作:
从
rxjs-operators
中引入您需要的操作符注意:由于与Javascript保留字冲突,以下运算符名字做了修改:
do
->tap
,catch
->catchError
,switch
->switchAll
,finally
->finalize
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
使用
pipe()
包裹所有的操作符方法。确保所有操作符间的.
被移除,转而使用,
连接。记住!!!有些操作符的名称变了!!!
以下为升级示例:// an operator chain
source
.map(x => x + x)
.mergeMap(n => of(n + 1, n + 2)
.filter(x => x % 1 == 0)
.scan((acc, x) => acc + x, 0)
)
.catch(err => of('error found'))
.subscribe(printResult); // must be updated to a pipe flow source.pipe(
map(x => x + x),
mergeMap(n => of(n + 1, n + 2).pipe(
filter(x => x % 1 == 0),
scan((acc, x) => acc + x, 0),
)),
catchError(err => of('error found')),
).subscribe(printResult);注意我们在以上代码中嵌套使用了
pipe()
。
使用函数而不是类
使用函数而不是类来操作可观察对象(Observables)。所有的Observable类已被移除。他们的功能被新旧操作符及函数替代。这些替代品的功能与之前的类功能一模一样。
示例如下:// removed
ArrayObservable.create(myArray) // use instead from(myArray) // you may also use new operator fromArray().有关替换
v5
类为v6
函数的完整列表,请查看RxJS文档。特殊情况
ConnectableObservable
在v6中不能直接使用,要访问它,请使用操作符multicast
,publish
,publishReplay
和publishLast
。SubscribeOnObservable
在v6中不能直接使用,要访问它,请使用操作符subscribeOn
移除
resultSelector
Result Selectors是一项没有被广泛使用甚至没有文档说明的RxJs特性,同时Result Selectors严重的增加了RxJs代码库的体积,因此RxJs团队决定弃用或删除他。
对于使用到该功能的开发人员,他们需要将
esultSelector
参数替换为外部代码。对于
first()
,last()
这两个函数,这些参数已被移除,在删除rxjs-compat
之前务必升级代码。对于其他拥有
resultSelector
参数的函数,如mapping
操作符,该参数已被弃用,并
以其他方式重写。如果您移除rxjs-compat
,这些函数仍可正常工作,但是RxJs团队声明他们必须在v7版本发布之前将其移除。针对该情况的更多详情,请查阅RxJs文档
其他RxJs6弃用
Observable.if
andObservable.throw
Observable.if
已被iif()
取代,Observable.throw
已被throwError()
取代。您可使用rxjs-tslint
将这些废弃的成员方法修改为函数调用。代码示例如下:
OBSERVABLE.IF > IIF()
// deprecated
Observable.if(test, a$, b$); // use instead iif(test, a$, b$);OBSERVABLE.ERROR > THROWERROR()
// deprecated
Observable.throw(new Error()); //use instead throwError(new Error());已弃用的方法
根据迁移指南,以下方法已被弃用或重构:
merge
import { merge } from 'rxjs/operators';
a$.pipe(merge(b$, c$)); // becomes import { merge } from 'rxjs';
merge(a$, b$, c$);concat
import { concat } from 'rxjs/operators';
a$.pipe(concat(b$, c$)); // becomes import { concat } from 'rxjs';
concat(a$, b$, c$);combineLatest
import { combineLatest } from 'rxjs/operators';
a$.pipe(combineLatest(b$, c$)); // becomes import { combineLatest } from 'rxjs';
combineLatest(a$, b$, c$);race
import { race } from 'rxjs/operators';
a$.pipe(race(b$, c$)); // becomes import { race } from 'rxjs';
race(a$, b$, c$);zip
import { zip } from 'rxjs/operators';
a$.pipe(zip(b$, c$)); // becomes import { zip } from 'rxjs';
zip(a$, b$, c$);总结
RxJS 6带来了一些重大改变,但是通过添加rxjs-compat软件包可以缓解这一问题,该软件包允许您在保持v5代码运行的同时逐渐迁移。对于Typescript用户,其他中包括大多数Angular开发人员,
tslint
提供了大量的自动重构功能,使转换变得更加简单。任何升级与代码修改都会引入一些bug到代码库中。因此请务必测试您的功能以确保您的终端用户最终接受到相同的质量体验。
RxJS 6有哪些新变化?的更多相关文章
- [转]Material Design Library 23.1.0的新变化与代码实战
Design Library出来已经快有一个月了,当时大概看了一下介绍这个新版本变化的译文,内容不多,给我印象最深的就是Percent lib.AppBarLayout 和NavigationView ...
- Material Design Library 23.1.0的新变化与代码实战
Design Library出来已经快有一个月了,当时大概看了一下介绍这个新版本变化的译文,内容不多,给我印象最深的就是Percent lib.AppBarLayout 和NavigationView ...
- 从iOS 11 UI Kit中谈谈iOS 11的新变化
北京时间9月20日凌晨1点,iOS 11终于迎来了正式版的推送,相信各位小伙伴已经在第一时间进行了升级.iOS 11毫无疑问是一次大规模的系统更新,UI.系统内核.锁屏等多方面都进行了不同程度的改进. ...
- Delphi XE7 GPS控件android下的新变化
Delphi XE7 GPS控件的Android新变化 GPS控件的Accuracy可以起作用了,Accuracy>0时: 1--100:ACCURACY_HIGH 101--500 ...
- 前端面试之HTML5的新变化
前端面试之HTML5的新变化 H5新增语义化标签 头部标签 <header> :头部标签 <nav> :导航标签 <article> :内容标签 <secti ...
- iOS8.3发布了Swift 1.2带来哪些新变化
苹果前几日在面向开发者推送iOS 8.3 Beta的同时,还发布了版本号为6D520o的Xcode 6.3 Beta,其中便包含了iOS 8.3 Beta和OS X v10.10 SDK,并进一步提升 ...
- [译] OpenStack Kilo 版本中 Neutron 的新变化
OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...
- [译] OpenStack Liberty 版本中的53个新变化
一个新的秋季,一个新的OpenStack 版本.OpenStack 的第12个版本,Liberty,在10月15日如期交付,而且目前发行版本已经备好了.那么我们期望能从过去六个月时间的开发中获得些什么 ...
- XCode9的新变化
XCode9已经随着ios11的发布发布了,那么在这个XCode9版本中有哪些变化呢? 1 折叠代码 焦点在方法的实现体的方法名上,按comman键,则整个函数会被框住.用来标志这个方法的起点和终点 ...
随机推荐
- 7.caffe:create_lmdb.sh(数据预处理转换成lmdb格式)
个人实践代码如下: #!/usr/bin/env sh # Create the imagenet lmdb inputs # N.B. set the path to the imagenet tr ...
- linux 的常用命令(2)
tail [必要参数] [选择参数] [文件] | 显示文件结尾内容 -v 显示详细的处理信息-q 不显示处理信息-num/-n (-)num 显示最后num行内容-n +num 从第 ...
- Linux基础使用
Linux中,日志所在的位置: /var/log/messages 系统默认的日志 /var/log/secure 记录用户的登录信息 查看日志的方法有很多 :head ...
- Python&Selenium自动化测试之PO设计模式
一.摘要 Page Object模式,后面简称PO,他是一种设计思想,在上一章节中,曾经列举了一些在编写自动化测试过程中随着代码量的增加导致的大量代码难以维护.难以扩展.可读性极差等灾难性的事件:那么 ...
- 在laravel5.8中集成swoole组件----用协程实现的服务端和客户端(nginx配置篇章)
laravel项目中的配置 原文出处:https://laravelacademy.org/post/19700.html,感谢原文作者让laravel这款可爱的php框架,进入了高并发的殿堂 如果 ...
- BZOJ 3744 Gty的妹子序列 分块+树状数组
具体分析见 搬来大佬博客 时间复杂度 O(nnlogn)O(n\sqrt nlogn)O(nnlogn) CODE #include <cmath> #include <cctyp ...
- addBack() 添加堆栈中元素集合到当前集合,一个选择性的过滤选择器。
addBack() 概述 添加堆栈中元素集合到当前集合,一个选择性的过滤选择器. 如上所述在讨论中的.end(), jQuery对象维护一个堆栈内部来跟踪匹配的元素集合的变化.当一个DOM遍历方法被调 ...
- window上git bash运行错误记录
错误现象:每次启动git bash报出如下错误gitbash 0 [main] bash 11928 fork: child -1 - CreateProcessW failed for 'D:\P ...
- C++全局变量的定义和声明
编译单元 编译分为两个步骤: 第一步:将每个.cpp或.c和相应的.h文件编译乘obj文件(包含预编译,汇编.编译) 第二部:将obj文件进行Link,生成最终的可执行文件 根据该阶段错误大致可分为两 ...
- ARM编辑、编译工具
手动编译 编译器问题,肯定是GNU的大名鼎鼎的GCC了,与此相关的什么连接器,汇编器也都包含在内了. 针对arm的GCC,当然就是arm-linux-gcc了,我所用的版本就是友善之臂光盘自带arm- ...