Firestore 排序列表 - 重复 API 调用 Firestore X 次以迭代 Firestore 文档的链接列表
Firestore sorted list - Repeat API call to Firestore X times to iterate over a linked list of Firestore documents
我正在 Firestore 中试验一个“链接列表”,它维护一个排序的事务列表。我期待大量的交易,所以我在玩无限滚动的想法,在初始加载时我们拉入最近的 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 operator. You can use the operator as described in the excellent article (rxjs core team member) here: expand explained
在示例中,获取了下一页(在您的交易案例中)one-by-one。我试图找到一个建议。
我终于使用 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
一直等到 [=29= 的上一个链] calls 发出了 n
个事务并立即将其作为数组发出。
bufferCount
的一个问题是如果 nTransactions % n != 0
您将丢失一些交易。为了解决这个问题,我想我只是要跟踪交易总数和我已经加载的总数。那么如果nTotal - nLoaded < n
我就设置n = nTotal - nLoaded
.
我正在 Firestore 中试验一个“链接列表”,它维护一个排序的事务列表。我期待大量的交易,所以我在玩无限滚动的想法,在初始加载时我们拉入最近的 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 operator. You can use the operator as described in the excellent article (rxjs core team member) here: expand explained
在示例中,获取了下一页(在您的交易案例中)one-by-one。我试图找到一个建议。
我终于使用 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
一直等到 [=29= 的上一个链] calls 发出了 n
个事务并立即将其作为数组发出。
bufferCount
的一个问题是如果 nTransactions % n != 0
您将丢失一些交易。为了解决这个问题,我想我只是要跟踪交易总数和我已经加载的总数。那么如果nTotal - nLoaded < n
我就设置n = nTotal - nLoaded
.