RxJS API解析(二)
Rx* (Observable.case)方法
方法定义
[Rx.Observable.case(selector, sources, [elseSource|scheduler])
]
作用
选择序列中特定可观察对象进行订阅,在特定可观察对象不存在的情况下,返回传入的默认可观察对象。
参数
selector
(Function
): 返回键的字符串的函数,键用以与sources
中的键名进行比较。sources
(Object
): 一个包含可观察对象的Javascript对象。[elseSource|scheduler]
(Observable
|Scheduler
):当selector
无法匹配sources
时,该对象被默认返回。 如果没有明确指定,将返回附加了指定Scheduler
的Rx.Observabe.empty
对象。
返回值
(Observable
): 返回值为经过选择后的Observable
(可观察对象)。
宝珠图
实例
var sources = { hello: Rx.Observable.just('clx'), world: Rx.Observable.just('wxq') }; var subscription = Rx.Observable.case(()=>"hello", sources, Rx.Observable.empty()) subscription.subscribe(function(x) { console.log(x) })
实例中,匿名函数()=>"hello"
指定需要在sources中返回的可观察对象的键名为"hello"
,命令行最终输出"clx"
,点击进入case()
实例。
题外话
键值对,可以对值进行命名。通过键值对可以构造命名的Observable
可观察对象。
键值对是Javascript对象的组成部分,键名可以方便进行查找和比较操作。
两个典型的使用场景中,数据都是用键值对表示的:通过Ajax
请求获得的数据,就是一个键值对(JSON'
对象);许多配置文件也是键值对写入并持久化的,比如数据库、缓存的配置。
典型的Ajax
请求结果
{ message: "ok", nu: "350430378480", companytype: "huitongkuaidi", ischeck: "1", com: "huitongkuaidi", updatetime: "2016-01-15 10:58:19", status: "200", condition: "F00", codenumber: "350430378480" }
Laravel 的数据库配置
'mysql' => [ 'read' => [ 'host' => '127.0.0.1', ], 'write' => [ 'host' => '127.0.0.1' ], 'driver' => 'mysql', 'database' => 'homestead', 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_general_ci', 'prefix' => '', 'strict' => false, ]
试想,我们从不同的其他服务器获取配置文件,那么整个获取配置的过程是异步的。
我们将获取的结果封装成可观察对象,再命名为如database
这样名称的键值对,使用case()
方法便可以在可观察对象发射时,执行相应的初始化操作。
var config = { "database": Observable.return("数据库配置"), "cache": Observable.return("缓存配置"), "picCDN": Observable.return("图片CDN配置,比如七牛") }; Observable.case(()=>'database', config, Observable.empty()) .subscribe((databaseConfig) => { // 连接数据库 }) Observable.case(()=>'picCDN', config, Observable.empty()) .subscribe((pciCDNConfig) => { // 初始化图片CDN })
把上面的例子分开写也没有什么问题:
Observable.return("数据库配置") .subscribe(function(databaseConfig) { // 链接数据库 }) Observable.return("图片CDN配置,比如七牛") .subscribe(function(picCDNConfig) { // 初始化图片CDN })
我们为何要多此一举去使用case()
呢?从结构化去考虑,将所有从远程获取配置的过程封装成config
对象更有实际意义,也更便于代码的维护和管理。
我们再看一个例子作为结束:例子是针对表单进行校验,校验用户的手机号
和邮箱
是否和服务器记录重复,将所有校验封装在validate
对象中结构更为合理:
var validate = { "mobile": Observable.return('123-566-789-01'), "email": Observable.return('[email protected]') }; var emptyObserable = Observable.empty(); validate.case(()=>'mobile', validate, empty) .subscribe(function(mobile){ // 验证手机号码是否重复 }) validate.case(()=>'email', validate, empty) .subscribe(function(email){ // 验证用户邮箱是否重复 })
剧终