Ignore/cancel/interrupt 函数式反应式编程中的流?
Ignore/cancel/interrupt streams in Functional reactive programming?
有没有办法cancel/ignore/interrupt一个流基于另一个流的输出?
用例是我有 3 个流:
- loginStream - 用户输入登录凭证并点击提交。发出登录凭据。
- authorizeStream- 系统尝试授权用户。发出令牌。
- logoutStream - 用户按下注销按钮
常见的情况是---用户登录,系统尝试授权,在未来的某个时候用户注销。这是非常标准的 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'))
上述方法应该可行,但我想知道是否有更简洁的 "more FRP" 方法来忽略 authorizationStream。
takeUntil
说 "stop emitting results from this stream when an element is emitted by this other stream",我想这就是你想要的。
此流仅在 login
之后且仅在 logout
:
之前发出
loginStream.flatMapLatest(() => {
return authorizeStream.take(1).takeUntilBy(logoutStream);
})
根据您的情况,您可以省略 .take(1)
部分以允许一次登录多次授权
有没有办法cancel/ignore/interrupt一个流基于另一个流的输出?
用例是我有 3 个流:
- loginStream - 用户输入登录凭证并点击提交。发出登录凭据。
- authorizeStream- 系统尝试授权用户。发出令牌。
- logoutStream - 用户按下注销按钮
常见的情况是---用户登录,系统尝试授权,在未来的某个时候用户注销。这是非常标准的 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'))
上述方法应该可行,但我想知道是否有更简洁的 "more FRP" 方法来忽略 authorizationStream。
takeUntil
说 "stop emitting results from this stream when an element is emitted by this other stream",我想这就是你想要的。
此流仅在 login
之后且仅在 logout
:
loginStream.flatMapLatest(() => {
return authorizeStream.take(1).takeUntilBy(logoutStream);
})
根据您的情况,您可以省略 .take(1)
部分以允许一次登录多次授权