RxJS API解析(三)
Rx* (Observable.catch)方法
方法定义
Rx.Observable.catch(...args)
作用
序列中可观察对象因为异常而被终止后,继续订阅序列中的其他可观察对象。
参数
args
(Array
| arguments
): 可观察对象序列。
返回值
(Observable
): 可观察对象序列中能够正确终止,不抛出异常的第一个可观察对象。
宝珠图
实例
var obs1 = Rx.Observable.throw(new Error('error')); var obs2 = Rx.Observable.return(42); var source = Rx.Observable.catch(obs1, obs2); var subscription = source.subscribe( x => console.log(`onNext: ${x}`), e => console.log(`onError: ${e}`), () => console.log('onCompleted')); // onNext: 42
在订阅时, obs1
抛出错误后,程序继续执行,转而输出没有异常的obs2
,并输出obs2
发射的值42
。点击进入在线演示。
题外话
服务可用性是指,服务提供者需要保证服务在任何时间、情况下正确地提供。比如联网的银行系统,用户在各个ATM终端进行提取现金等操作后,数据都会被及时同步和备份。当不可抗因素发生时,数据可以被尽快的通过备份恢复。通常这些解决方案被称为灾备处理。
使用云服务,例如Ucloud的Redis
服务,可以在同一个服务上看到两个不同地址访问地址,文档描述如下:
每个云内存存储实例都会提供两个IP进行访问。
这两个IP都可以对云内存存储实例进行访问,分布在不同的接入服务上,其作用在于,当其中一个IP无法正常访问时,仍有另一个IP可用,不会完全中止服务。
因此,应用程序可以增加一个容灾切换的逻辑处理:将访问的IP列表设置好,默认访问其中的一个IP,当该IP无法访问时,自动切换到另一个IP继续业务。
文档中提到了增强服务可用性的线索:总是提供一组相同的服务而不是一个服务,或者至少是相似的服务,服务调用后可以完成相同的业务逻辑。
这个策略也是负载均衡的基础,可以缓解单个服务提供者的压力,从用户角度看,又感知不到服务的差异性:比如 多个HTTP服务 、_读写分离的数据库_。
文末,举一个实例:假设你需要做一个APP,APP中用户在通过手机验证码验证后,才能登录账户。
许多第三方服务提供商,都提供手机验证服务,比如_LeanCloud_,调用者像服务提供方发送POST
请求,请求的body
为用户手机号码。然后服务提供者,会将验证码发送到用户手机。用户在收到验证码后,通过表单,输入验证码,提交后,调用者再次向服务提供商发起POST
请求,请求的body
为用户输入的验证码然后等待服务提供商响应。
当然,某些情况下,服务提供商可能自己挂了,或者是不支持向某个号码所属的运营商提供服务;还有些情况下,用户的号码可能在某个服务提供商的黑名单中。比如:你的一个用户是 经常写竞品分析的产品经理 ,可能也许大概你的号码就在某个服务提供商的黑名单中。
我们往往要同时接入多个服务提供商的短信验证服务,保证用户能够正常通过我们的注册(登录)流程:
回到catch()
函数,结合定义我们可以把一个提供商作为主要服务提供者,如果其不能提供服务(调用失败),我们可以选择第二家作为候选:
var service1 = Observable.create("服务提供商#1"); var service2 = Observable.create("服务提供商#1"); Observable.catch(service1, service2).subscribe({ ()=>console.log('succeed'), ()=>console.log('所有验证服务均不可用') ()=>console.log('completed') })
这样,用户能够收到验证码并成功验证的几率大大增加。
剧终