Akita Collection Service 中的 SyncCollection 太贵了?
SyncCollection in Akita Collection Service too expensive?
我对 akita-ng-fire
模块中可用的 CollectionService()
方法有疑问。我创建了一个扩展 CollectionService() 的服务,并使用 syncCollection 来保持 firestore 文档和我的网络客户端之间的同步。这是服务定义的样子:
@Injectable({providedIn: 'root'})
@CollectionConfig({path: 'someDoc/:customId/anotherDoc'})
export class MyService extends CollectionService<WorkspaceState> {
constructor(store: WorkspaceStore) {
super(store);
this.store.setHasCache(true, {restartTTL: true});
}
// service methods ......
}
我在组件的 onInit
指令中使用它来初始化同步。
ngOnInit() {
this.sub = this.myService.syncCollection().pipe(
concatMap(_ => this.query.myDoc$.pipe(
tap(d => this.myService.markActive(d.customId)),
tap(d => this.customId = d.customId),
)),
tap(d => this.router.navigate(['somePlace', d. customId])),
).subscribe();
}
但是,我看到此同步每分钟进行约 5 次读取。有没有办法减少这个?我觉得这对我来说很昂贵,因为我们将此服务作为核心服务,用于与关键业务文档保持同步。
社区的任何建议都会有所帮助
使用first
运算符在收到数据后自动取消订阅
ngOnInit() {
this.sub = this.myService.syncCollection().pipe(
concatMap(_ => this.query.myDoc$.pipe(
tap(d => this.myService.markActive(d.customId)),
tap(d => this.customId = d.customId),
)),
first((d) => {
const hasData = !!d;
return hasData;
})
tap(d => this.router.navigate(['somePlace', d. customId])),
).subscribe();
}
syncCollection
监听您 collection 上每个文档的每次更改。这是一个很好的开始,但是一旦您的应用程序发展壮大,您就需要更加精确。
- 只在需要时同步:使用
syncCollection
用于包含列表的页面,syncDoc
用于包含单个视图的页面。离开页面时不要忘记取消订阅(我喜欢为此目的使用 Guards)。
- 如果您不需要总是 up-to-date,考虑使用快照 和
getValue
。在某些情况下,您不想实时执行读取,例如 none-collaborative 表单,或者只显示一个不应更改的键的列表。在这种情况下,您可以将 getValue()
用于 collection 或将 getValue(id)
用于文档。
- 使用 queryFn 监听更少的文档。大多数时候你不想得到整个 collection 而只是其中的一个子集:
syncCollection(ref => ref.limitTo(10).where(...)
.
- 不用太担心价格。您将支付一些欧元/数百万的阅读费用。与 firebase 的读取成本相比,你花在优化它上的时间对你的公司来说会花费更多。编写代码时将价格牢记在心,但不要花太多时间进行优化 ;)。
作为旁注,我认为 setHasCache
在这里不会有任何影响。 Firebase 使用 IndexedDB 来缓存您已经使用过的数据。因此,如果自上次以来没有任何变化,您无需为此付费。
我对 akita-ng-fire
模块中可用的 CollectionService()
方法有疑问。我创建了一个扩展 CollectionService() 的服务,并使用 syncCollection 来保持 firestore 文档和我的网络客户端之间的同步。这是服务定义的样子:
@Injectable({providedIn: 'root'})
@CollectionConfig({path: 'someDoc/:customId/anotherDoc'})
export class MyService extends CollectionService<WorkspaceState> {
constructor(store: WorkspaceStore) {
super(store);
this.store.setHasCache(true, {restartTTL: true});
}
// service methods ......
}
我在组件的 onInit
指令中使用它来初始化同步。
ngOnInit() {
this.sub = this.myService.syncCollection().pipe(
concatMap(_ => this.query.myDoc$.pipe(
tap(d => this.myService.markActive(d.customId)),
tap(d => this.customId = d.customId),
)),
tap(d => this.router.navigate(['somePlace', d. customId])),
).subscribe();
}
但是,我看到此同步每分钟进行约 5 次读取。有没有办法减少这个?我觉得这对我来说很昂贵,因为我们将此服务作为核心服务,用于与关键业务文档保持同步。
社区的任何建议都会有所帮助
使用first
运算符在收到数据后自动取消订阅
ngOnInit() {
this.sub = this.myService.syncCollection().pipe(
concatMap(_ => this.query.myDoc$.pipe(
tap(d => this.myService.markActive(d.customId)),
tap(d => this.customId = d.customId),
)),
first((d) => {
const hasData = !!d;
return hasData;
})
tap(d => this.router.navigate(['somePlace', d. customId])),
).subscribe();
}
syncCollection
监听您 collection 上每个文档的每次更改。这是一个很好的开始,但是一旦您的应用程序发展壮大,您就需要更加精确。
- 只在需要时同步:使用
syncCollection
用于包含列表的页面,syncDoc
用于包含单个视图的页面。离开页面时不要忘记取消订阅(我喜欢为此目的使用 Guards)。 - 如果您不需要总是 up-to-date,考虑使用快照 和
getValue
。在某些情况下,您不想实时执行读取,例如 none-collaborative 表单,或者只显示一个不应更改的键的列表。在这种情况下,您可以将getValue()
用于 collection 或将getValue(id)
用于文档。 - 使用 queryFn 监听更少的文档。大多数时候你不想得到整个 collection 而只是其中的一个子集:
syncCollection(ref => ref.limitTo(10).where(...)
. - 不用太担心价格。您将支付一些欧元/数百万的阅读费用。与 firebase 的读取成本相比,你花在优化它上的时间对你的公司来说会花费更多。编写代码时将价格牢记在心,但不要花太多时间进行优化 ;)。
作为旁注,我认为 setHasCache
在这里不会有任何影响。 Firebase 使用 IndexedDB 来缓存您已经使用过的数据。因此,如果自上次以来没有任何变化,您无需为此付费。