Ignore/cancel/interrupt 函数式反应式编程中的流?

Ignore/cancel/interrupt streams in Functional reactive programming?

有没有办法cancel/ignore/interrupt一个流基于另一个流的输出?

用例是我有 3 个流:

  1. loginStream - 用户输入登录凭证并点击提交。发出登录凭据。
  2. authorizeStream- 系统尝试授权用户。发出令牌。
  3. 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) 部分以允许一次登录多次授权