跟我学Rx编程——局部循环逻辑

背景

有时候,我们会遇到这种情况,事件流从一个switch到另一个,某种情况下需要从头再来一遍,比如A->B->C->A->……循环不断,这时候怎么写比较好呢?
一种写法是在subscribe里面调用“调用自身的函数”

let obA = ……
function logic(){
  obA.subscribe(...,()=>{
    logic()
  })
}

上面的伪代码里面调用了logic函数后,我们开始执行obA这个Observable的逻辑,完成后我们会立即再次调用logic,形成循环。

这种写法的不够优雅,会反复的订阅事件流,当然也不能说是错的,但是在某些场合就不适用了,比如A->B->C->D->B->C->……可能循环在B-C这段,那么上面的写法就实现不了。下面我提供一种业务场景来说明如何写

业务逻辑

  1. 执行一个远程请求获取敏感数据
  2. 如果返回特定的错误信息则进行弹窗验证身份(要求输入短信验证码)
  3. 验证不通过则再次验证,直到通过为止
  4. 验证通过,则返回有效数据

涉及操作符

  • catchError
  • switchMapTo

变量定义

let getDataOb //获取数据的Observable
let verifyOb //身份验证请求Observable

当订阅getDataOb的时候会发出请求,如果不是正常返回值,就抛出错误,此处我们省略了该Observable的创建过程
当订阅verifyOb 的时候会发出身份验证的请求,这里也省略了该Observable的创建过程,这个Observable可能是一个有多个步骤的事件流,比如需要等待用户点击发送验证码按钮等。跟我学Rx编程———获取验证码

实现过程(伪代码)

let verifyOp = catchError(err=>{
  if(err.code==VERIFY){
    return verifyOb.pipe(verfiyOp)
  }
})
getDataOb.pipe(verifyOp).subscribe(……)

伪代码已经简化了,去掉了不相干的成分。verifyOp 是一个操作符,放到外面声明,在其内部可以访问到自身的引用。
我们用到了操作符catchError,用来捕获错误,当产生特定的错误的时候,我们会返回一个Observable——verifyOb.pipe(verfiyOp),这个Obserable如果还发生错误,就会继续被捕获,形成循环,或者说递归,因为是异步请求所以严格的说不能称为递归。

思考

我们写同步代码的时候一般就用

while(condition){
}

来进行循环即可
但是当业务很复杂,需要很多异步逻辑的时候,这种写法的复杂度就会成几何级上升。此时我们使用Rx编程,可以让代码在形式上仍然保持类似递归调用的样子,方便理解整体业务,代码也更为健壮。

今天的案例可以用于其他类似的循环逻辑结构中,不局限于例子中的业务逻辑。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,270评论 25 709
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 14,471评论 2 59
  • 爱走在恨前, 拉近了分别。 恨走在爱前, 离远了河边。
    雅俗共赏Y阅读 1,332评论 2 4
  • 以后做什么千万不要墨迹,想做什么就做什么,太为别人考虑,也别对别人太好,会让人我习惯,女生也一定要学会自重不管发生...
    86c8b121f8e1阅读 1,410评论 0 1
  • 没有什么比自己的进步更让人自信啦,最近找到了让我自信的好方法,我画我心
    川妈V爱阅读阅读 1,170评论 0 2