问题描述
此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,{}))
.subscribe(data => console.log(data));
...
subscriptionnorm = collectionData(query,"id")
.pipe(
map(v => v.reduce((a,c) =>
Object.assign(a,{})
),)
.subscribe(data => console.log(data));
解决方法
您对rxjs reduce运算符的假设是正确的。
“在源Observable上应用累加器函数,并且 源完成后返回累积的结果”-从文档中查看,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,{}))),).subscribe(data => console.log(data));