在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,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之外是她的

解决方法

我在这里看到多个问题

  1. 您正在订阅forEach。因此,每个元素将构成一个单独的订阅。相反,您可以使用forkJoincombineLatestzip之类的RxJS函数来并行订阅多个可观察对象。

  2. 您正在尝试同步访问异步变量articlepanier。您尝试在订阅之外访问它的时间尚未调整。您需要使用switchMap之类的RxJS运算符来使整个流具有反应性。

尝试以下

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,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 
    }
  }
);

请注意,我正在使用RxJS from函数将this.storage.get(TOKEN_KEY)函数返回的Promise转换为可观察的。最好与Promises或Observables一起使用,而不要结合使用。我还使用RxJS filter运算符检查令牌是否仍然有效。