2

我正在尝试学习如何在事件流中进行思考,并且试图通过在一些人为的场景中对其进行测试来围绕它进行思考。我坚持以下情况:

假设我有两个按钮,我们将它们称为ABA可以随时点击。B也可以被点击,但前提A是之前被点击过。换句话说,B永远不能连续点击两次。这是相应的弹珠图(其中 x 表示事件被忽略):

clickA$ --------o--------o-------->
                |        |
clickB$ --o--o--|--o--o--|--o--o-->
          x  x  |  |  x  |  |  x
logA$   --------o--|-----o--|----->
                   |        |       
logB$   -----------o--------o----->

标准方法是将状态存储在标志中并使用 if/else 控制块做出决策,如下所示:

var a = document.getElementById('a');
var b = document.getElementById('b');
var flag = false;

a.attachEventListener('click', function(e){
  flag = true;
  console.log("A");
});
b.attachEventListener('click', function(e){
  if (flag) {
    flag = false;
    console.log("B");
  }
});

我觉得应该有一种干净、简洁的方式来做到这一点,而不需要标志或一些超级混乱的事件流合并,但它让我无法理解。RxJS 中是否有一个someMethod()这样我们可以执行以下操作以获得预期的效果?

var a = document.getElementById('a');
var b = document.getElementById('b');
var a$ = Rx.Observable.fromEvent(a, "click").map(e => "A")
var b$ = Rx.Observable.fromEvent(b, "click").map(e => "B")
           .someMethod(a$)
a$.subscribe(x => console.log(x))
b$.subscribe(x => console.log(x))
4

1 回答 1

1

我假设它logB$是一个热源,就像clickA$.

看起来像logA$= clickA$

对于logB$

logB$ = clickA$.flatMapLatest(function (clickA){
          return clickB$.take(1);
        });

flatMapLatest允许您从 中获取值clickA$,并将其与流相关联,此处clickB$.take(1)flatMapLatest因此将从该流发出值直到它完成,它将在发出第一个发出的值之后clickB$(因为take(1))。当一个新值 fromclickA$到来时,从前一个值派生的前一个 observable 被取消订阅,从新值派生的 observable 被订阅。这给了你预期的行为。

文档链接:

于 2016-02-03T02:39:25.897 回答