为什么flatMap和fromEvent仅在第一次订阅期间返回时才起作用?

时间:2016-02-05 06:33:48

标签: rxjs flatmap

如下所示,为什么示例1在返回div时失败,然后分别将新的单击可观察flatMap返回到click$

示例2工作正常。下面的JSBin试一试

任何人都可以解释为什么会这样?根据我的理解,flatMap扩展了Observable。 http://jsbin.com/sowodi/3/edit?js,console,output



// Example 1
() => {
  let stream = Rx.Observable.fromArray([1, 2, 3]);

  let div$ = stream.map(i => {
    let div = document.createElement('div');
    div.innerHTML = `NOT WORKING DIV ${i}`;
    return div;
  })

  div$.subscribe(div => {
    document.querySelector('body').appendChild(div);
  })

  let click$ = div$.flatMap(
    div => Rx.Observable.fromEvent(div, 'click')
  );

  click$.subscribe(click => console.log('click'));
}();


// Example 2
() => {
  let stream = Rx.Observable.fromArray([4, 5, 6]);

  let click$ = stream.flatMap(i => {
    let div = document.createElement('div');
    div.innerHTML = `DIV ${i}`;
    document.querySelector('body').appendChild(div);

    return Rx.Observable.fromEvent(div, 'click');
  })

  click$.subscribe(click => console.log('click'));
}();

<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>

<body>
  <div id="app">
    THE APP ID
  </div>
</body>

</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

这是因为在你的第一个例子中你创建了两组div。你完成了相同的工作:

  Rx.Observable.fromArray([1, 2, 3])
    .map(i => {
      let div = document.createElement('div');
      div.innerHTML = `NOT WORKING DIV ${i}`;
      return div;
    }).subscribe(div => {
      document.querySelector('body').appendChild(div);
    })

  Rx.Observable.fromArray([1, 2, 3])
    .map(i => {
      let div = document.createElement('div');
      div.innerHTML = `NOT WORKING DIV ${i}`;
      return div;
  }).flatMap(
      div => Rx.Observable.fromEvent(div, 'click')
  ).subscribe(click => console.log('click'));

为什么,这是因为fromArray创建了一个cold Observable,这意味着每个订阅都会创建一个全新的独立版本,不会影响您创建的任何其他流。

有两种方法可以修复它,1)你已经发现它只是创建一个流来容纳你的所有逻辑,或者2)你可以将div $的结果变成热{{1}这样所有订阅实际上将共享相同的流。这将伴随着它自己的一系列问题,即如果你不小心你现在可以错过信息,但是重构你的第一个案例它最终会看起来像:

Observable