问题描述
我对返回 350 条记录的 API 发出 HTTP 请求。每个项目都有一个名为“total”的属性。我需要随机选择 5 个项目,而且这 5 个项目的“总”属性总和应该小于 30。我认为这可以使用 takeuntil 来完成,但我仍然没有知道如何构建代码以实现这一目标。
products$ = combineLatest([
this._productService.robots$,this.refreshProductAction$
]).pipe(
map(([products,action]) =>
products.sort(() => (Math.random() - Math.random())).slice(0,5),)
);
这是“扩展”运算符的一个示例,但我不知道如何跟踪总和并在高于 50 的情况下再次重新执行可观察对象。
解决方法
如果我理解正确,您会收到 350 个“产品”,并且只调用一次 API,如果 5 个随机选择的“产品”的“总和”大于 50,则需要重复此操作。
因此,如果这种理解是正确的,我将继续使用 expand
运算符递归调用 API,直到满足所需条件,然后使用 last
运算符仅通知发出的最后一个值,这是第一个满足条件的。下面的例子试图用内联注释解释逻辑。
products$ = combineLatest([
this._productService.robots$,this.refreshProductAction$
]).pipe(
// use expand operator to recursively repeat the API call if the sum is higher than 50,// otherwise return the empty Observable,which means simply to complete the stream
expand(([products,action]) => {
const fiveProducts = products.sort(() => (Math.random() - Math.random())).slice(0,5);
// use the "reduce" method of Array to calculate the sum
const sumOfFiveTotals = fiveProducts.reduce((s,p) => s = s + p.total,0);
return sumOfFiveTotals > 50 ?
// I assume this._productService.robots$,when subscribed,calls the API
// you can pipe a "delay" operator after this._productService.robots$ if you want to add some delay between subsequent API calls
this._productService.robots$ :
EMPTY // the empty Observable
}),// notifies only the last value emitted by the upstream
last()
);