今天讲一个简单的例子
业务逻辑
- 发起一个异步请求
- 收到请求结果的时候如果不足2秒,则等待到2秒再播放动画
- 如果超过2秒,则立即播放动画
假设有一个播放动画的函数play(data),并且用到了异步请求结果中的数据
这是一个游戏里面常用的逻辑,就是动画是用来填补等待时间,但不能由于异步太快结束后使得动画过早播放。也就是说需要营造一种花时间完成的错觉。但异步时间是不好确定的,可能异步会消耗很多时间,这时候又需要真实反映异步所花费的时间。
常规写法
代码语言:javascript复制let requestDone = false
let timeoutDone = false
let requestData = null
setTimeout(function(){
if(requestDone)play(requestData)
else timeoutDone = true
},2000)
request('http://xxx',function(data){
requestData = data
if(timeoutDone )play(data)
else requestDone = true
})
本质上,这种逻辑就是互相等待的过程,是十分常见的。
Rx写法
我们需要创建一个requestOb,这个就省略了 我们还需要一个timeout 的Observable,也可以用interval
代替,当然自己创建一个也非常简单
const timeout = period => Observable.create(observer=>setTimeout(() => {
observer.next(0)
observer.complete()
}, period))
现在就可以用combineLatest将两个Observable进行组合
代码语言:javascript复制combineLatest(requestOb,timeout(2000)).subscribe(x=>play(x[0]))
如果使用interval的话:
代码语言:javascript复制combineLatest(requestOb,interval(2000).pipe(take(1))).subscribe(x=>play(x[0]))
任何一个Observable先到达数据都不会立即发出组合事件对象,只有双方都到达的时候才会将一个结果数组发送出来
本次案例中的两个Observable都只会发出一个事件就会结束,combineLatest也可以用于发出多个事件的事件流的组合,每次都会在新的事件到达的时候,将所有Observable中最新的事件组合在一起。可以说combineLatest是一个非常有用的组合Observable的利器。