从2个可观察数据中获取一次数据

时间:2016-11-01 18:20:21

标签: javascript angular rxjs observable angularfire2

我有2个observable,我需要只获取一次可观察数据。

我所做的是在订阅中订阅,虽然它们可以在同一时间(并行)执行。

let table = this.af.database.object('tables');
    table.subscribe((tableData) => {
      let section_seats =  this.af.database.object('sections').take(1)
      .subscribe((sectionData) => {
          //Here I'm Using tableData  & sectionData
});
});

上面的代码效果很好,但它们不会在同一时间执行,尽管它们可以。

如何同时执行两个observable然后使用从这两个观察者收到的数据?

更新:使用forkJoin()不执行任何操作(以下代码中没有控制台日志)

var source = Observable.forkJoin(
  this.af.database.object('tables'),
  this.af.database.object('sections')
);

var subscription = source.subscribe(
  function (x) {
    console.log('Next: %s', x);
  },
  function (err) {
    console.log('Error: %s', err);
  },
  function () {
    console.log('Completed');
  });

4 个答案:

答案 0 :(得分:1)

有许多方法(阅读,操作员)可以帮助您组合来源。可以在Combining multiple observable sequences into a single sequence部分找到常规资源here。对于您的具体问题,这里有一个似乎可以削减的简短列表:

  • combineLatest:在1.两个源发出至少一个值时发出一个值,2。之后,任何一个源都会发出一个值。

例如:Rx.Observable.combineLatest(object('tables'), object('sections').take(1))

  • withLatestFrom:在第一个源发出值时发出一个值。发射的值包括第二个源的最新发射值。

例如:object('tables').withLatesFrom(object('sections').take(1))

  • zip:当BOTH源发出一个值时,会发出第一个值。通过相同的过程发出第N个值。

例如:Rx.Observable.zip(object('tables'), object('sections').take(1))

每个运算符都有类似但略有不同的语义。我认为combineLatest是你需要的,但是检查文档,设置一些代码并尝试一些东西,如果这不起作用,请回过头来发布。

答案 1 :(得分:0)

您应该使用withLatestFrom运算符。

withLatestFrom

上查看更多内容
/* Have staggering intervals */
var source1 = Rx.Observable.interval(140)
    .map(function (i) { return 'First: ' + i; });

var source2 = Rx.Observable.interval(50)
    .map(function (i) { return 'Second: ' + i; });

// When source1 emits a value, combine it with the latest emission from source2.
var source = source1.withLatestFrom(
    source2,
    function (s1, s2) { return s1 + ', ' + s2; }
).take(4);

var subscription = source.subscribe(
    function (x) {
        console.log('Next: ' + x.toString());
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
    });

// => Next: First: 0, Second: 1
// => Next: First: 1, Second: 4
// => Next: First: 2, Second: 7
// => Next: First: 3, Second: 10
// => Completed

答案 2 :(得分:0)

forJoin的文档解释了它:

  

并行运行所有可观察序列并收集它们的最后一个元素。

我认为 last 元素是在observable完成之前触发的最后一个元素,因此传递给forkJoin的所有Observable都必须在发出任何内容之前完成。

因为你只想要第一个发射元素,所以尝试让每个Observable在第一次发射之后完成:

var source = Observable.forkJoin(
  this.af.database.object('tables').take(1),
  this.af.database.object('sections').take(1)
);

答案 3 :(得分:0)

试试这个:

   var source = Observable.forkJoin(
      this.af.database.object('tables'),
      this.af.database.object('sections')
    );

var subscription = source.subscribe(
 data => {
       console.log(data[0]);
       console.log(data[1]);
      },
      err => console.error(err)
);