RxJS在可观察的条件满足时停止foreach

时间:2019-09-09 18:05:10

标签: typescript rxjs rxjs-pipeable-operators

我有一个对象数组。我必须通过API调用检查每个对象,以查看该对象是否符合特定促销条件。 保持对对象调用API的最佳方法是什么,直到最后一个对象被调用,在该对象中可观察对象应返回false,或者其中一个对象从API获得真实状态?

目前,我将此作为代码,但感觉RxJS运算符应该有更好的方法。

checkProductForPromo(items: []) {
   const promoChecker$ = new EventEmitter<boolean>();

   items.forEach((item, key, arr) => {
        // This does a HTTP callback to the API
        this.ApiService.getProductInformation(item).subscribe(
            (product) => {
                // Based on some properties this will return true or false of the product is eligible for the promo.
                if (product.isEligibleForPromo()) {
                    promoChecker$.emit(true);
                } else if (Object.is(arr.length - 1, key)) {
                    promoChecker$.emit(false);
                }
            }
        );
    });

    return promoChecker$;
}

1 个答案:

答案 0 :(得分:4)

您可以使用from运算符创建一个Observable:

checkItemsForPromo(items: any[]) {
  return from(items).pipe(
    concatMap(item => this.ApiService.getProductInformation(item)),
    map(product => !!product.isEligibleForPromo()),
    takeWhile(isEligible => !isEligible, true)    
  );
}

此Observable依次为每个项目调用API。它等待上一个请求完成,然后再发送下一个请求。 map运算符根据需要将发射设置为truefalse

takeWhile表示Observable将继续发出false,直到出现true值为止,此时它将完成。传递给true的{​​{1}}参数实际上是包含性标志,这意味着Observable 在完成之前发出单个takeWhile值。

如果您只希望它在完成后发出true一次,而不是为每个不合格的产品发出,请尝试在false上添加distinctUntilChanged()

不要忘记订阅此方法返回的Observable,并在必要时取消订阅。