6

Rx* (Observable.catch)方法

方法定义

Rx.Observable.catch(...args)

作用

序列中可观察对象因为异常而被终止后,继续订阅序列中的其他可观察对象。

参数

args (Array | arguments): 可观察对象序列。

返回值

(Observable): 可观察对象序列中能够正确终止,不抛出异常的第一个可观察对象。

宝珠图

catch

实例

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终端进行提取现金等操作后,数据都会被及时同步和备份。当不可抗因素发生时,数据可以被尽快的通过备份恢复。通常这些解决方案被称为灾备处理

使用云服务,例如UcloudRedis服务,可以在同一个服务上看到两个不同地址访问地址,文档描述如下:

每个云内存存储实例都会提供两个IP进行访问。

这两个IP都可以对云内存存储实例进行访问,分布在不同的接入服务上,其作用在于,当其中一个IP无法正常访问时,仍有另一个IP可用,不会完全中止服务。

因此,应用程序可以增加一个容灾切换的逻辑处理:将访问的IP列表设置好,默认访问其中的一个IP,当该IP无法访问时,自动切换到另一个IP继续业务。

文档中提到了增强服务可用性的线索:总是提供一组相同的服务而不是一个服务,或者至少是相似的服务,服务调用后可以完成相同的业务逻辑。
这个策略也是负载均衡的基础,可以缓解单个服务提供者的压力,从用户角度看,又感知不到服务的差异性:比如 多个HTTP服务 、_读写分离的数据库_。

文末,举一个实例:假设你需要做一个APP,APP中用户在通过手机验证码验证后,才能登录账户。

verifyMobile

许多第三方服务提供商,都提供手机验证服务,比如_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')
})

这样,用户能够收到验证码并成功验证的几率大大增加。

剧终


mumuzhenzhen
1.7k 声望557 粉丝