在功能反应式编程中忽略/取消/中断流?

时间:2016-04-10 03:54:38

标签: rxjs bacon.js kefir.js

有没有办法根据另一个流的输出取消/忽略/中断流?

用例是我有3个流:

  1. loginStream - 用户输入登录信用卡并点击提交。发出登录信用证。
  2. authorizeStream-系统尝试授权用户。发出一个令牌。
  3. logoutStream - 用户按下注销按钮
  4. 常见的情况是---用户登录,系统尝试授权,将来某个时候用户注销。这是非常标准的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。

2 个答案:

答案 0 :(得分:2)

此流仅在login之后,仅在logout

之前发出
loginStream.flatMapLatest(() => {
    return authorizeStream.take(1).takeUntilBy(logoutStream);
})

根据您的情况,您可以省略.take(1)部分以允许多次授权进行一次登录

答案 1 :(得分:0)

takeUntil说“当另一个流发出一个元素时,停止从此流中发出结果”,我认为这就是你想要的。