组合多个 FirebaseListObservables [英] Combining multiple FirebaseListObservables

查看:21
本文介绍了组合多个 FirebaseListObservables的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

const placeId = this.getPlaceId();
        this.af.database.list(`placeUsers/${placeId}`).subscribe((userKeys) => {
            for (let index = 0; index < userKeys.length; index++) {
                let userKey = userKeys[index];

                this.af.database.list(`userDevices/${userKey.$key}`).subscribe((deviceKeys) => {

                    for (let index = 0; index < deviceKeys.length; index++) {
                        let deviceKey = deviceKeys[index];

                        this.af.database.object(`devices/${deviceKey.$key}`).subscribe((device) => {

                            console.log(device);
                            // Device received.    

                        });
                    }
                });
            }
        });

我目前正在尝试向所有关注某个地点的用户发送通知.目前的流程是这样的:

I'm currently trying to send notifications to all my users that are following a place. The current flow goes like this:

  • 获取属于某个地点的用户(placeUsers 节点)
  • 获取属于用户的设备密钥(userDevices 节点)
  • 从 deviceKeys(设备节点)获取设备

我想知道是否有办法将所有这些调用组合成一个可观察的调用.

I was wondering if there was a way to combine all these calls into a single observable call.

我目前的问题是,我无法知道所有这些请求何时完成.我研究了 RxJs,它可以让我将所有这些可观察对象结合起来.但是我还没有找到一个很好的解决方案来说明如何使用四个节点来做到这一点.

What my current problem is, is that i am unable to know when all of these requests are done. I've looked into RxJs, which would allow me to combine all these observables. But i haven't found a good solution on how to do it with four nodes.

推荐答案

您可以使用 concatMapforkJoin 来组成一个发射设备的 observable.这个组合的 observable 将发出单个设备数组,然后将完成(因为 first 运算符用于仅获取第一个发出的列表或对象):

You can use concatMap and forkJoin to compose an observable that emits the devices. This composed observable will emit a single array of devices and will then complete (as the first operator is used to take only the first emitted list or object):

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/concatMap';
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/forkJoin';

this.af.database
  .list(`placeUsers/${placeId}`)
  .first()
  .concatMap(userKeys => {
    let observables = userKeys.map(userKey => this.af.database
      .list(`userDevices/${userKey.$key}`)
      .first()
    );
    return observables.length ?
      Observable.forkJoin(...observables, (...lists) => [].concat(...lists)) :
      Observable.of([])
  })
  .concatMap(deviceKeys => {
    let observables = deviceKeys.map(deviceKeys => this.af.database
      .object(`devices/${deviceKey.$key}`)
      .first()
    );
    return observables.length ?
      Observable.forkJoin(...observables) :
      Observable.of([])
  })
  .subscribe(devices => console.log(devices));

如果你想要一个不完整的 observable 并且在一个地方的用户或他们的设备发生变化时发出一个地方的设备,请使用 switchMap 而不是 concatMapcombineLatest 而不是 forkJoin 并删除 first 运算符:

If you want an observable that does not complete and emits the devices for a place whenever the users for a places or their devices change, use switchMap instead of concatMap, combineLatest instead of forkJoin and remove the first operators:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/combineLatest';
import 'rxjs/add/operator/switchMap';

this.af.database
  .list(`placeUsers/${placeId}`)
  .switchMap(userKeys => {
    let observables = userKeys.map(userKey => this.af.database
      .list(`userDevices/${userKey.$key}`)
    );
    return observables.length ?
      Observable.combineLatest(...observables, (...lists) => [].concat(...lists)) :
      Observable.of([])
  })
  .switchMap(deviceKeys => {
    let observables = deviceKeys.map(deviceKeys => this.af.database
      .object(`devices/${deviceKey.$key}`)
    );
    return observables.length ?
      Observable.combineLatest(...observables) :
      Observable.of([])
  })
  .subscribe(devices => console.log(devices));

这篇关于组合多个 FirebaseListObservables的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆