由于 Angular 中的服务调用延迟,数组未正确更新

Posted

技术标签:

【中文标题】由于 Angular 中的服务调用延迟,数组未正确更新【英文标题】:Array is not updating properly due to delay in service calls in 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 循环之后的语句。请帮我解决给定的问题。

【问题讨论】:

【参考方案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 来模拟你正在尝试做的事情。请检查一下。

以上是关于由于 Angular 中的服务调用延迟,数组未正确更新的主要内容,如果未能解决你的问题,请参考以下文章

Angular组件未从服务加载数据[重复]

Angular 2:可观察订阅未正确读取数据[重复]

表单未预先填充Angular 8

在遍历两个数组时无法读取未定义的属性'id':Angular

由于休息api延迟,视图寻呼机中的第一个片段未显示

angular-js cors 请求未到达服务器