【问题标题】:Empty result after execute first observable subscribe inside foreach to end?在 foreach 中执行第一个可观察订阅结束后的空结果?
【发布时间】:2020-10-09 06:45:08
【问题描述】:

我正在使用 ionic 3,angular 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

【问题讨论】:

  • 是否进入stockbyarticle 内部?你用控制台日志检查过吗?这将帮助您确切地卡在哪里或从forEach出来。
  • stockbyarticle 是 provider 中的一个函数。是的,我已经在控制台中签入了,但是返回的是空的。

标签: angular rxjs ionic3


【解决方案1】:

我在这里看到了多个问题

  1. 您在forEach 内订阅。因此,每个元素都将构成一个单独的订阅。相反,您可以使用 forkJoin、combineLatest 或 zip 等 RxJS 函数来并行订阅多个可观察对象。

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

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

【讨论】:

  • 谢谢,你帮了我很多!这些解释让我感觉很好,我会试试这个!
  • 谢谢先生,这就是解决方案
猜你喜欢
  • 2018-11-16
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
相关资源
最近更新 更多