首页 > 解决方案 > 在 foreach 中执行第一个可观察订阅结束后的空结果?

问题描述

我正在使用离子 3,角度 5,我不确定我的代码有什么问题,我的结果总是在 foreach 中没有可观察的。这是我的代码:

articlepanier : Article[] = [];
    this.storage.get(TOKEN_KEY).then(token => {
      let isExpired = helper.isTokenExpired(token);
      if(!isExpired){  
        //foreach loop 
        this.cart.forEach((element, index) => {
        var article = new Article();
        article.artid = element.artid;
        article.artcode = element.artcode;
        //value of the sales unit quantity
        article.plvqteuv = element.amount;
        
        let data = {
            pricode: this.pricode,
            artcode: element.artcode
        };

        //use observable to return stock available in the database  
        //and change the value of the article.plvqtyisvalid by false value at each line 
        //if the quantity entered exceeds the quantity available
        this.cardProvider.stockbyarticle(data).subscribe((res: any) => {
          if( res.quantity < element.amount ){
            //change boolean status quantity is valid
            article.plvqtyisvalid = false;
          }
          
          //method changes the contents of array
          this.articlepanier.splice(index, 0, article);
          
            console.log(this.articlepanier);
        });
            
    });

    //Here outside of foreach, I want the result of array after executing foreach (this.articlepanier) to be used in a if condition 
    //But articlepanier is always empty

    if(this.articlepanier.filter(c =>(c.plvqtyisvalid  == true).length > 0){
        //recording the cart in database 
    }
  
  });

我想要在 foreach 内部观察到的结果,但是 this.articlepanier 总是空的,她在外部 foreach

标签: angularrxjsionic3

解决方案


我在这里看到多个问题

  1. 您正在订阅forEach. 因此,每个元素都将构成一个单独的订阅。相反,您可以使用 RxJS 函数,如forkJoin,combineLatestzip并行订阅多个 observables。

  2. 您正在尝试articlepanier同步访问异步变量。当您尝试在订阅之外访问它时,它尚未调整。您需要使用 RxJS 运算符(如switchMap.

尝试以下

import { from, forkJoin } from 'rxjs';
import { filter, map, switchMap } from 'rxjs/operators';

from(this.storage.get(TOKEN_KEY)).pipe(
  filter(token => !(helper.isTokenExpired(token))),
  switchMap(_ => {
    return forkJoin(this.cart.map((element, index) => {
      const article = new Article();
      article.artid = element.artid;
      article.artcode = element.artcode;
      article.plvqteuv = element.amount; //value of the sales unit quantity
      let data = {
        pricode: this.pricode,
        artcode: element.artcode
      };
      return this.cardProvider.stockbyarticle(data).pipe(
        tap((res: any) => {
          if (res.quantity < element.amount) { // change boolean status quantity is valid
            article.plvqtyisvalid = false;
          }
          this.articlepanier.splice(index, 0, article); // method changes the contents of array
          console.log(this.articlepanier);
        })
      )
    }))
  })
).subscribe(
  res => {
    if (this.articlepanier.filter(c => (c.plvqtyisvalid == true).length > 0)) {
      // recording the card in database 
    }
  }
);

注意我使用 RxJSfrom函数将从函数返回的 Promise 转换为this.storage.get(TOKEN_KEY)observable。最好使用 Promises 或 Observables,而不是结合它们。我还使用 RxJSfilter运算符来检查令牌是否仍然有效。


推荐阅读