7

首先,抱歉标题太长了。

我正在尝试使用来自angularfire2的forEach订阅一系列连续流,但我还想在确认第一组数据已进入后运行一个函数:

this.people.forEach((person) => {
    person.items = this.database.list('/items' + person.key);
    person.items.subscribe((data) => {person.itemsList = data});
});

myIntendedFunction();

有没有办法这样放置myIntendedFunction()

  1. data它在每个 接收到第一个流之后运行person,并且
  2. 它只运行一次?
4

3 回答 3

6

如果您不希望第一个请求发生两次,这会有点复杂:

const connectables: ConnectableObservable<any>[] = [];

this.people.forEach(person => {
    person.items = this.database.list('/items' + person.key);
    const connectable = person.items.publish();
    connectables.push(connectable);
    connectable.subscribe((data) => {person.itemsList = data});
});

Observable.zip(...connectables).take(1).subscribe(myIntendedFunction);

connectables.forEach(c => c.connect());

这里发生的事情是这样的: 的效果publish()基本上是可以多次订阅同一个数据流。此外,在您调用之前不会调用订阅功能connect()。如果我们使用person.items.share()which is sugar for person.items.publish().connect(),它将立即发出请求,并且我们的应用程序可能由于竞争条件而出现错误。

zip()等待每个通过的 observable 发出一个项目,并一次将这些项目作为一个数组发出。我们只希望这发生在第一组项目上,所以我们只是take(1).

于 2016-08-22T13:22:23.687 回答
0

这并不完全是您想要实现的目标。据我了解,您在收到第一个人后尝试调用“myIntendedFunction”。您可以多次订阅您的 observable(订阅顺序很重要)并使用 first() 运算符仅获取第一个值,然后取消订阅。

this.people.subscribe((person) => {
    person.items= this.database.list('/items');
    person.items.subscribe((data) => {person.itemsList = data});
});

this.people.first().subscribe(myIntendedFunction);
于 2016-08-22T09:06:11.733 回答
0

使用 on firebase list 的.first()运算符import 'rxjs/add/operator/first'将获取列表中的初始值。如果没有此运算符,您的函数将被多次调用,并可能导致浏览器崩溃。的 .toPromise()操作员 import 'rxjs/add/operator/toPromise' 会将获得的可观察列表转换为承诺。你可以使用.then()promise 来运行你想要的函数。

    this.forEach.person((people) => {
        person.items = this.database.list('/items' + person.key);
        person.items
            .first()
            .toPromise()
            .then(() => {
                myIntendedFunction();
         });
    })
于 2018-02-19T06:51:21.883 回答