【问题标题】:Turn observable into array将 observable 变成数组
【发布时间】:2018-06-24 01:46:04
【问题描述】:

在使用 FireStore 和 Angular 5 时,我的数据作为 Observables 交付。这意味着每次数据库中的数据发生变化时,都会导致一次新的读取(因此据我了解,我要为此付费)。

我不想要这种“不断重新加载,不断充电”的功能。 我想要一次读取,将我的数据存储在数组中,然后关闭连接。

这是我当前的代码。如何修改我的服务以在从 FireStore 检索产品时将产品存储在一个数组中,以便对我的服务的所有后续调用都从该数组(如缓存)返回数据,而无需再次调用 FireStore?

product.service.ts

products: Observable<Product[]>; // *** I want this to be an array of Product objects, not an observable

getProductsAll(): Observable<Product[]> {

    return this.afs.collection( 'products', ref => ref.orderBy( 'published', 'desc' ) ).snapshotChanges()
        .map( actions => {
            return actions.map( a =>  {
                const id = a.payload.doc.id; 
                const data = a.payload.doc.data() as Product;
                return { id, ...data };
            })
        })

products.component.ts

items: any;

ngOnInit(): void {

    this.productService.getProductsAll()
        .subscribe( products => { 
            this.items = products;
        })
}

就上下文而言,我的小测试应用程序导致读取过多并达到 FireStore 每天 50,000 次读取的配额,而数据库中只有 100 个文档。

【问题讨论】:

标签: angular google-cloud-firestore


【解决方案1】:

这是我想出的!似乎正在做我想做的事。它还有一个额外的优势,即在第一次从 FireStore 读取数据后,页面会使用“缓存”数据显着更快地加载。

但是,如果这是一个好的解决方案,或者是否有更好的解决方案,我真的很感激如果有人可以解释

本质上,我将 Observable 转换为 Promise,使用 take(1),并使用 if 语句来避免再次访问 FireStore。

服务

productsP: Promise<Product[]>;

getProductsAll(): Promise<Product[]> {

    // get from cache if possible
    if( !this.productsP ) {
        console.log("Getting all products from FireStore...");
        this.productsP = this.afs.collection( 'products', ref => ref.orderBy( 'published', 'desc' )).snapshotChanges()
        .map( actions => {
            return actions.map( a =>  {
                const id = a.payload.doc.id; 
                const data = a.payload.doc.data() as Product;
                return { id, ...data };
            })
        }).take(1).toPromise();
    }
    else {
        console.log("Getting all products from cache...");
    }

    return this.productsP;
}

组件:将 'subscribe' 更改为 'then'。

【讨论】:

  • 我会用 take 运算符以同样的方式处理这个问题。但是,我会使用 shareReplay 运算符而不是 toPromise 将其保持为可观察的。
【解决方案2】:

我没有测试过这个。但您可以在订阅前致电.take(1)

products.component.ts

items: any;

ngOnInit(): void {

    this.productService.getProductsAll()
        .take(1).subscribe( products => { 
            this.items = products;
        })
}

【讨论】:

    猜你喜欢
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 2020-09-14
    • 2019-03-05
    • 1970-01-01
    相关资源
    最近更新 更多