有没有办法根据另一个流的输出取消/忽略/中断流?
用例是我有3个流:
常见的情况是---用户登录,系统尝试授权,将来某个时候用户注销。这是非常标准的FRP。
Common case
loginStream: -------------------o---->
authorizeStream: ---------------a-------->
logoutStream: ---------l-------------->
边缘情况是---用户登录但在授权之前立即注销。
Edge case
loginStream: -------------------o---->
authorizeStream: --------a---------------> //ignore/cancel/interrupt this event
logoutStream: -------------l---------->
为了防止系统进入奇怪的状态,我需要在这种特殊情况下忽略授权流。我唯一能想到的是(1)合并三个流,(2)通过扫描跟踪状态,(3)注销将状态设置为logout
,登录将状态设置为login
。不在login
时过滤掉授权事件。
merge([loginStream, authorizeStream, logoutStream])
.scan((state, event) => event.type !== 'auth' ? {state: event.type, event} : {state, event}, {})
.filter(event => !(event.state !== 'login' && event.event.type === 'auth'))
上述方法应该有效,但我想知道是否有一种更清晰,更“FRP”的方式忽略authorizationStream。
答案 0 :(得分:2)
此流仅在login
之后,仅在logout
:
loginStream.flatMapLatest(() => {
return authorizeStream.take(1).takeUntilBy(logoutStream);
})
根据您的情况,您可以省略.take(1)
部分以允许多次授权进行一次登录
答案 1 :(得分:0)
takeUntil
说“当另一个流发出一个元素时,停止从此流中发出结果”,我认为这就是你想要的。