【问题标题】:angular how to wait sucbribe response before for each iterate to next element角度如何在每次迭代到下一个元素之前等待订阅响应
【发布时间】:2020-05-06 02:39:30
【问题描述】:

我的每个循环都有一个 pb。

我想在我的用户列表上进行迭代,对于每个用户,我都会调用一个 api 来获取其他一些统计信息。但循环在第一个元素的调用响应之前转到下一个。

我不明白 for each 是同步的,而不是订阅...所以我该怎么做呢?

这是我的代码源:

 this.users.forEach(userid => {
    this.httpClient.get(url).subscribe((res: DayStat[]) => {
      res.forEach(y => {
          // do some stuff
          console.log('log1');
      }
    });

    // do some others stuffs
    console.log('log2');
  });

  console.log ('end loop');
  // do some others stuffs;

日志顺序:

end loop;
log1
log2

感谢您的帮助!

【问题讨论】:

  • 不清楚您的要求

标签: angular foreach subscribe


【解决方案1】:

Jeff,http.get 是异步的,所以你不知道它什么时候结束。

当我们想要有一系列的httpClient时,通常你使用forkJoin。在 forkJoin 里面你有所有的响应,例如

const obs=[];
this.users.forEach(userid => {
    obs.push(this.httpClient.get(url))
}
//In obs we has an array of observables. when subscribe you get an array with the responses, e.g.

forkJoin(obs).susbcribe((result:any[])=>{
   result.map((res,index)=>{
      console.log(this.users[index], res)
   })
})

【讨论】:

  • 我不会将 observable 推送到数组中,而是简单地将用户映射到 observable 中,如下所示:const obs = this.users.map(userid => this.httpClient.get(url))。否则很好的答案。
  • 真的,这是一个更好的方法
【解决方案2】:

这是因为 http 请求是异步的,这个解决方案应该会有所帮助

async method() {
  for (const userid of this.users) {
    const res: DayStat[] = await this.httpClient.get(url).toPromise();
    res.forEach(y => {
      // do some stuff
      console.log('log1');
    });
    console.log('log2');
  }

  console.log ('end loop');
  // do some others stuffs;
}

【讨论】:

  • 哇!感谢你的帮助 !谢谢达米安,您的解决方案对我有用!只需在此处添加结果类型:get.
  • 哦,对不起。我在盲目的情况下编写了这段代码,但尽管如此,你还是达到了目标,这很好:)
  • 我不喜欢将 observables 转换为 promise,它失去了 observables 的力量。
  • 在这种情况下,它是否可观察并不重要,因为它在响应后立即完成,它不会发出任何新值,所以它的行为类似于 promise
【解决方案3】:

这样的?

const requests$: Observable<DayStat[]>[] = users.forEach(user => getUserById(user.id));
zip(...requests$).subscribe();

【讨论】:

    【解决方案4】:

    您可以使用这里已经提到的“等待”:https://stackoverflow.com/a/48697112/1143214

    【讨论】:

    • 这是行不通的,因为 forEach 不是异步函数,所以 await 是不允许的。可以允许,如果你在userid 前面添加async 这样async userid =&gt;,但整个表达式仍然是异步的,可以先执行console.log('end loop');
    猜你喜欢
    • 2019-11-29
    • 2020-04-08
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 2020-11-19
    • 2021-10-15
    • 1970-01-01
    • 2018-05-20
    相关资源
    最近更新 更多