RxFire handels firestore如何查询
How does RxFire handels firestore queries
这个 js reduce 可以很好地处理查询结果:
function toc(current) {
return {....};
};
function getToc(data) {
return = data.reduce((a, c) => Object.assign(a, {[c.id]: toc(c)}), {});
};
const query = db.collection(normCollection)
.where('a_id', '==', a_id )
.where('year', '==', year)
.orderBy("id");
subscriptionNorm = collectionData(query, "id")
.subscribe(data => console.log(getToc(data)));
但是当我使用 RxJs reduce 时,它停止工作了。它与流结束有关,但是......但是我不明白 RxFire / RxJs 如何处理流式 firestore 查询结果:
...
subscriptionNorm = collectionData(query, "id")
.pipe(reduce((a, c) => Object.assign(a, {[c.id]: toc(c)}), {}))
.subscribe(data => console.log(data));
更新这个工作正常,但是......:
...
subscriptionNorm = collectionData(query, "id")
.pipe(
map(v => v.reduce((a, c) =>
Object.assign(a, {[c.id]: toc(c)}), {})
),
)
.subscribe(data => console.log(data));
您关于 rxjs reduce 运算符的假设是正确的。
"Applies an accumulator function over the source Observable, and
returns the accumulated result when the source completes" - from the docs, see here: RxJS reduce docs
在您的情况下,源不会完成,因为这就是 Firestore 的工作方式,它 运行 无休止地没有完成,直到发生错误或您手动取消订阅。
举个粗略的例子,你可以在管道中使用 take(1)
运算符,它会在发出 1 个事件后完成源 Observable,因此 reduce
会起作用, 但是它扼杀了 Firestore Observable 背后的主要思想。
这是您可以使用 rxjs reduce
运算符的方式:
subscriptionNorm = collectionData(query, "id").pipe(
switchMap(data => from(data).pipe(
reduce((a, c) => Object.assign(a, { [c.id]: toc(c) }), {})
)),
).subscribe(data => console.log(data));
这是可能的,因为我正在切换到 from(data)
并且内部 Observable 将完成,因此 reduce
运算符将按您的预期工作。
但是,老实说,这是一种矫枉过正,您可以简单地保持已经实施的方式:
subscriptionNorm = collectionData(query, "id").pipe(
map(data => data.reduce((a, c) => Object.assign(a, { [c.id]: toc(c) }), {}))),
).subscribe(data => console.log(data));
这个 js reduce 可以很好地处理查询结果:
function toc(current) {
return {....};
};
function getToc(data) {
return = data.reduce((a, c) => Object.assign(a, {[c.id]: toc(c)}), {});
};
const query = db.collection(normCollection)
.where('a_id', '==', a_id )
.where('year', '==', year)
.orderBy("id");
subscriptionNorm = collectionData(query, "id")
.subscribe(data => console.log(getToc(data)));
但是当我使用 RxJs reduce 时,它停止工作了。它与流结束有关,但是......但是我不明白 RxFire / RxJs 如何处理流式 firestore 查询结果:
...
subscriptionNorm = collectionData(query, "id")
.pipe(reduce((a, c) => Object.assign(a, {[c.id]: toc(c)}), {}))
.subscribe(data => console.log(data));
更新这个工作正常,但是......:
...
subscriptionNorm = collectionData(query, "id")
.pipe(
map(v => v.reduce((a, c) =>
Object.assign(a, {[c.id]: toc(c)}), {})
),
)
.subscribe(data => console.log(data));
您关于 rxjs reduce 运算符的假设是正确的。
"Applies an accumulator function over the source Observable, and returns the accumulated result when the source completes" - from the docs, see here: RxJS reduce docs
在您的情况下,源不会完成,因为这就是 Firestore 的工作方式,它 运行 无休止地没有完成,直到发生错误或您手动取消订阅。
举个粗略的例子,你可以在管道中使用 take(1)
运算符,它会在发出 1 个事件后完成源 Observable,因此 reduce
会起作用, 但是它扼杀了 Firestore Observable 背后的主要思想。
这是您可以使用 rxjs reduce
运算符的方式:
subscriptionNorm = collectionData(query, "id").pipe(
switchMap(data => from(data).pipe(
reduce((a, c) => Object.assign(a, { [c.id]: toc(c) }), {})
)),
).subscribe(data => console.log(data));
这是可能的,因为我正在切换到 from(data)
并且内部 Observable 将完成,因此 reduce
运算符将按您的预期工作。
但是,老实说,这是一种矫枉过正,您可以简单地保持已经实施的方式:
subscriptionNorm = collectionData(query, "id").pipe(
map(data => data.reduce((a, c) => Object.assign(a, { [c.id]: toc(c) }), {}))),
).subscribe(data => console.log(data));