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){
// 验证用户邮箱是否重复
})
剧终