跟我学Rx编程———获取验证码

从本例中我们将用到

  • fromEvent
  • interval
  • map
  • take
  • tap
  • switchMapTo

业务逻辑

  1. 点击获取验证码按钮
  2. 获取验证码按钮置灰,并开始N秒倒计时
  3. 倒计时结束按钮恢复可点击状态

常规写法

var enabled = true
var remainTime = N
var id = null
sendBn.on('click',function(){
  if(enabled){
    sendSms()
    enabled = false
    gray(true)
    remainTime = N
    id  = setInterval(cooldown,1000)
  }
})
function cooldown(){
  remainTime --
  sendBn.label = remainTime + "秒后可重新获取"
  if(remainTime==0){
    clearInterval(id)
    enabled = true
    sendBn.label = "发送"
    gray(false)
  }
}

功能不是很复杂,但是如果你不是首先看了前面的业务逻辑,而是直接看代码,就需要稍微的理解一下才能看出里面包含了这3条逻辑。接下来我们通过Rx编程,来实现这个业务逻辑

首先我们需要一个点击事件流sendOb,每次点击按钮都会从这个sendOb中派发事件

let sendOb = fromEvent(sendBn,'click')//获取验证码点击事件

这虽然看上去和回调函数差不多,但组合起来才会显示出Rx的威力

我们还需要一个事件流用来产生倒计时

let coolDownOb = rxjs.interval(1000).pipe(map(_ => N - _), take(N))

说明一下interval(1000)会产生每秒一次的事件,0,1,2,3……
map操作,转换成了N,N-1,N-2,……(如果N=60,那么相当于60,59,58……)
take(N)操作,会在第N个事件到达后,完成事件流,interval(1000)将会停止派发事件

interval会在内部进行clearInterval操作。

下面是完成点击后发送验证码的逻辑,并且随后产生倒计时事件

let getVCodeOb = sendOb.pipe(take(1), tap(() => {
    sendSms()//发送获取验证码的请求
    gray(true)//显示灰色的按钮
}), switchMapTo(coolDownOb))

take(1)使得按钮的点击在订阅后只有一次有效(狂点按钮,只有第一次有效而已),如果需要再次有效,就再次订阅(也可以使用其他方法实现这种逻辑)
switchMapTo会使得事件触发后,激活coolDownOb事件流,并让订阅者开始接受这个事件流的事件。

最后我们需要订阅这个事件流,让逻辑运行起来

function enableGetVCode () {
    gray(false)//恢复可点击状态
    getVCodeOb.subscribe(num => sendBn.label = num + "秒后可重新获取", console.error, enableGetVCode)
}
enableGetVCode()

subscribe第三个参数是完成事件,我们将enableGetVCode传入,形成“循环”。按钮会再次被监听,开始新一轮的获取验证码

使用Rx编程后

  • 不再需要定义状态变量
  • 逻辑分离成完整的若干条
  • 方便修改逻辑
  • 可以组合出更多的逻辑,从而复用基本逻辑

你可能感兴趣的:(跟我学Rx编程———获取验证码)