我正在尝试一个"链接列表";在Firestore中维护一个排序的事务列表。我期望有大量的事务,所以我在玩无限滚动的想法,在初始加载时,我们拉入最近的X事务,然后根据需要加载更多的X批次。
Transactions
是一个文档集合,每个文档代表一个事务。每个文档包含对下一个文档(即下一个最近的事务)名称的引用。
例如
Transaction A
nextDocId: 'Transaction B'
Transaction B
nextDocId: 'Transaction C'
Transaction C
nextDocId: 'Transaction D'
在给定起始事务的情况下,加载X事务的最佳方式是什么?如果我只是为X选择一个值(比如10),我可以将10个switchMaps/concatMaps
链接在一起,但是有没有一种方法可以动态地做到这一点?我基本上需要重复一个API调用X次,但每次调用都需要上次调用的响应。
或者,这个解决方案是否可行?在Firestore中,我看不到任何其他维护排序列表的方法,所以另一个选择是每次在客户端中对整个事务列表进行排序。
我终于得到了这个工作使用expand
和bufferCount
。这里有一些技巧,第一个是在它自己的函数中定义Firestore调用,以使递归像预期的那样工作,
private getNextTransactionRequest(txnId: string): Observable<any> {
return this.firestore.collection('myCollection').doc(txnId).snapshotChanges().pipe(
map(response => {
return response.payload.data();
})
);
}
然后,将调用串在一起,
public loadTransactions(headTxnId: string, n: number): Observable<any[]> {
const getNextTransaction$ = this.getNextTransactionRequest(headTxnId);
return getNextTransaction$.pipe(
expand(txn => {
if (txn) {
if (txn.nextTransactionId && txn.nextTransactionId != '') {
return this.getNextTransactionRequest(txn.nextTransactionId);
}
}
}),
bufferCount(n),
take(1)
);
}
expand
使用前一个调用的响应递归地将API调用链在一起,这正是我所需要的,bufferCount
等待直到上一个API调用链发出n
事务,并立即将其作为数组发出。
bufferCount
的一个问题是,如果nTransactions % n != 0
,您将丢失一些事务。为了解决这个问题,我想我只需要跟踪交易的总数和我已经加载的总数。然后如果nTotal - nLoaded < n
我只设置n = nTotal - nLoaded
您应该看看展开操作符。您可以在这里使用优秀文章(rxjs核心团队成员)中描述的操作符:expand explained
在这个示例中,下一页(在您的案例中是事务)被逐一获取。我想找个建议。