RxJS API解析(二)

Rx* (Observable.case)方法

方法定义

[Rx.Observable.case(selector, sources, [elseSource|scheduler])]

作用

选择序列中特定可观察对象进行订阅,在特定可观察对象不存在的情况下,返回传入的默认可观察对象。

参数

  1. selector (Function): 返回的字符串的函数,用以与sources中的键名进行比较。

  2. sources (Object): 一个包含可观察对象的Javascript对象。

  3. [elseSource|scheduler] (Observable | Scheduler):当selector无法匹配sources时,该对象被默认返回。 如果没有明确指定,将返回附加了指定SchedulerRx.Observabe.empty 对象。

返回值

(Observable): 返回值为经过选择后的Observable(可观察对象)。

宝珠图

RxJS API解析(二)

实例

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

剧终

相关推荐