RxJS问题:如何延迟Observable.if中else分支的执行?
这个问题我之前也碰到过!核心原因是RxJS的Observable.if会立即创建两个分支的Observable实例——也就是说,不管你的条件判断结果如何,Observable.of(nodeActions.treasure...)里的nodeActions.treasureSomeAction(t.genesisHash)表达式会被直接执行,而不是等到条件满足才执行。所以哪怕t是undefined,这段代码还是会去访问t.genesisHash,自然就报错了。
解决方案:用defer延迟Observable创建
你需要用defer操作符把每个分支的创建逻辑包裹起来,这样只有当对应的分支被订阅时,才会执行里面的代码。修改后的代码如下:
return Observable.if( () => !t, Observable.defer(() => Observable.of(nodeActions.requestGenesisHashes())), Observable.defer(() => Observable.of(nodeActions.treasureSomeAction(t.genesisHash))) );
如果你的项目用的是RxJS 6及以上版本,更推荐使用官方主推的iif操作符,写法类似,同样配合defer:
import { iif, defer, of } from 'rxjs'; return iif( () => !t, defer(() => of(nodeActions.requestGenesisHashes())), defer(() => of(nodeActions.treasureSomeAction(t.genesisHash))) );
额外优化提示
如果nodeActions.requestGenesisHashes()或者nodeActions.treasureSomeAction()本身就返回Observable的话,你甚至不需要用of包裹,直接在defer里返回它们就行:
return Observable.if( () => !t, Observable.defer(() => nodeActions.requestGenesisHashes()), Observable.defer(() => nodeActions.treasureSomeAction(t.genesisHash)) );
原理说明
defer操作符会把Observable的创建逻辑包装在一个函数里,只有当这个分支被订阅时,才会执行这个函数并创建对应的Observable。这样当t是undefined时,else分支的函数根本不会被调用,也就不会触发t.genesisHash的访问错误了。
内容的提问来源于stack exchange,提问作者bigpotato
相关产品推荐
相关产品推荐

