【问题标题】:Array is not updating properly due to delay in service calls in Angular由于 Angular 中的服务调用延迟,数组未正确更新
【发布时间】:2021-11-09 03:08:48
【问题描述】:

我使用 while 循环多次调用同一个服务,但由于 API 响应延迟,我的数组没有正确更新。我想在 while 循环和所有服务响应完成后调用某些语句。

 GetData(){
    var xyz = [];
    var pqr = [];
    this.startRow = 0;
    this.names=[];
    while(this.startRow <= this.num)
    {
      this.getEmpData();
      this.startRow = this.startRow + this.countRow;
      console.log("Pass1");
      console.log(this.names);
    }
    //due to delay in API response name array is coming as empty
    this.names.forEach(value => {
      xyz.push(value);
    });
   
  }
  getEmpData()
  {    
     this.empService.getEmpData(this.startRow,this.countRow,this.id,this.search).subscribe(data => {
        this.resp = data;
        this.names = this.names.concat(this.resp); 
        console.log(this.names);   
      })
   
  }

回应

Pass1
[]
Pass1
[]
(20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
(40) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

我希望仅在 while 循环中更新名称,或者在更新名称数组后执行 while 循环之后的语句。请帮我解决给定的问题。

【问题讨论】:

    标签: angular typescript rxjs angular8


    【解决方案1】:

    尝试在您的 getEmpData() 方法中使用 async-await:

     async getEmpData()
      {    
          const data = await this.empService.getEmpData(this.startRow,this.countRow,this.id,this.search).toPromise();
          this.resp = data;
          this.names = this.names.concat(this.resp); 
          console.log(this.names);
      }
    

    【讨论】:

    • 感谢您的回复,但给定的方法对我不起作用。我仍然面临同样的问题。
    • 您实际上也需要在 this.getEmpData(); 上进行等待,因为这也需要等待。不过,我建议您在订阅中的this.getEmpData(); 之后执行您所做的所有事情。这样你就不需要明确地使用 async/await 了。例如。你会将data 推送到xzy 中(所以是分块而不是一次)。
    • 谢谢@GunnarB。是的,我也试过了,但问题是它在 API 响应之前直接进入增量语句。我在这两个函数上都尝试过异步等待,但这对我不起作用。
    【解决方案2】:

    您可以通过以下方式实现:

    • 使用expand 运算符,在条件有效时重复调用getEmpData 方法。
    • 使用reduce 运算符“在源 Observable 上应用累加器函数,并在源完成时返回累加结果,给定一个可选的种子值。”
    • getEmpData 方法返回 observable,而不是订阅它。
    getData() {
      var xyz = [];
      var pqr = [];
      this.startRow = 0;
      this.names = [];
    
      this.getEmpData()
        .pipe(
          expand(() => {
            this.startRow = this.startRow + this.countRow;
            return this.startRow <= this.num ? this.getEmpData() : EMPTY;
          }),
          reduce(acc => acc)
        )
        .subscribe(() => {
          xyz.push(...this.names);
        });
    }
    
    getEmpData(): Observable<any> {
      return this.empService
        .getEmpData(this.startRow, this.countRow, this.id, this.search)
        .pipe(
          tap(data => {
            this.resp = data;
            this.names = this.names.concat(this.resp);
            console.log(this.names);
          })
        );
    }
    

    【讨论】:

    • 非常感谢@Amer 付出了这么大的努力,我已经尝试过您的方法 getEmpData() 方法被按需调用,但在完成所有调用后,它不会转到 subscribe 方法。对此的任何建议都会有所帮助。
    • 可以stackBiltz吗?
    • 请确保您完全按照上述建议进行操作。谢谢。
    • 是的,我所做的与您在答案中建议的完全一样。减少和订阅方法存在一些问题。执行reduce 操作后,调用不会进入subscribe 方法。抱歉,给定代码无法使用 stackblitz,因为给定部分还有很多其他依赖项,但非常感谢您的努力。
    • 我创建了这个工作 stackBiltz 来模拟你正在尝试做的事情。请检查一下。
    猜你喜欢
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 2014-06-14
    • 2017-01-08
    • 2020-04-05
    相关资源
    最近更新 更多