【发布时间】:2020-11-11 03:23:51
【问题描述】:
我无法在另一个 Observable 中获取 Observable 的内部数字属性的总和(或任何减少)。
我有一个可观察的“帐户”对象数组 (Observable<AppAccount[]>)。
export interface AppAccount {
_id?: string;
name: string;
}
还有一个“余额”对象的 Observable 数组,每个对象都有一个 accountId。许多余额可以与一个帐户相关联(按日期排序/过滤,但为简洁起见,该部分已删除)
export interface AccountBalance {
_id?: string;
accountId: string;
amount: number;
}
我有一个帮助方法,它只返回给定帐户的最后一个余额对象的金额。
getLastAmount(account: AppAccount): Observable<number> {
return this.balanceService.balances$.pipe(
map(balances => {
let last = balances.filter(balance => {
return balance.accountId === account._id;
}).sort().pop();
//console.log(last)
return last ? last.amount : 0;
}),
tap(amount => console.log(`getLastAmount() => ${amount}`)),
);
}
现在我正在尝试编写一个方法,该方法将遍历帐户,为每个帐户调用 getLastAmount(),然后将它们全部相加并返回一个 Observable。这是我到目前为止所管理的:
getTotalBalance(accounts$: Observable<AppAccount[]>): Observable<number> {
return accounts$.pipe(
map(accounts => from(accounts)),
mergeAll(),
mergeMap(account => this.getLastAmount(account)),
reduce((sum, current) => {
console.log(`${sum} + ${current}`);
return sum + current;
}, 0)
);
}
但这似乎永远不会返回,并陷入无限循环??
只有一个帐户和一个余额关联,余额的“金额”为“10”,我从控制台日志中得到这个:“0 + 10”一遍又一遍,网络日志也确认它是连续调用 getBalances()。
我在正确的轨道上吗?有没有更好的办法?为什么这个 RXJS 管道会卡在一个循环中?
编辑:我根据 picci 的建议做了一些更改:
getTotalBalance(accounts$: Observable<AppAccount[]>): Observable<number> {
return accounts$.pipe(
map(accounts => accounts.map(account => this.getLastAmount(account))),
concatMap(balances$ => { console.log('balances$', balances$); return forkJoin(balances$); }),
tap(balances => console.log('balances', balances)),
map(balances => balances.reduce(
(amountSum, amount) => {
console.log(`${amountSum} + ${amount}`)
amountSum = amountSum + amount;
return amountSum
}, 0))
);
}
但这仍然没有返回,或者管道没有完成? 我在这里做了一个stackblitz:https://stackblitz.com/edit/angular-rxjs-nested-obsv 如果您检查控制台输出,它似乎没有比 forkJoin 调用更进一步......
【问题讨论】:
-
不确定无限循环,但我认为它不会返回,因为您使用的是
reduce,它将在源(在本例中为accounts$)完成时发送减小的值.如果您想在每次 reduce 迭代 时接收值,您可能需要使用scan。
标签: angular rxjs sum rxjs-observables rxjs-pipeable-operators