【问题标题】:How to wait until http.get is finished in angular如何等到http.get以角度完成
【发布时间】:2019-07-06 15:24:55
【问题描述】:

我一直在尝试将值添加到我的 data 数组中,但是我遇到了一个问题,它在返回 getValue 函数的值之前到达 data.push()。我一直在尝试修复它,但无法想出解决方案,感觉有点迷失在这里。

这是我形成数据的函数:

formData() {
  for (const id of Object.keys(this.cols)) {
    let p= cols[id];
    switch (p.name) {
      case 'a':
      this.temp.name= this.addValue(m, p);
        break;
      case 'b':
        let idx = 1;
        let surname= this.getValue(idx);
        break;
    }
  }
  this.data.push(this.temp);
});

这就是我的 getValue 函数的样子:

 getValue(id: string) {
let url = this.baseUrl + '/streams/' + id+ '/data?';
url += 'from=' + from + '&';
url += 'to=' + to;
this.http.get(url).map(r => r.json()).subscribe((response: any) => {
        if (response.data.values[0] !== null && response.data.values[0] !== undefined) {
         return response.data.values[0];
        }
}, (error: any) => {
    return null;
});

如何避免在该值实际存在之前将数据推送到数组?

【问题讨论】:

  • 您没有订阅该服务。服务返回一个 Observable,组件订阅。阅读有关 RxJS 和 observables 的 Angular 文档。
  • 这个问题有很多内容。您正在遍历一个数组,其中每个循环可能需要也可能不需要对服务的异步调用,然后您希望等待所有异步调用都已解决,然后再在循环结束时执行某些操作!
  • 您可以(并且应该)订阅formData(),但要提供答案,您必须显示formData() 的完整代码(您似乎没有)。在this.addValue(m, p)m 来自哪里?在let surname= this.getValue(idx); 中,您实际上对返回值做了什么? surname 从未使用过!如果您只使用idthis.cols 获取值,for (const id of Object.keys(this.cols)) 可能是for (const p of Object.values(this.cols))

标签: angular typescript subscription


【解决方案1】:

如何避免在该值实际存在之前将数据推送到数组?

将其从订阅中链接,例如

this.http.get(url).map(r => r.json()).subscribe((response: any) => {
        if (response.data.values[0] !== null && response.data.values[0] !== undefined) {
         // NOTE
         this.loadFormData();
        }

【讨论】:

  • 在 Angular 的最新版本中,这种类型的 HTTP 请求不起作用,不需要 .map() 因为......如果我没记错的话,5......还有订阅(response: any) 不应转换为“any”... :)
【解决方案2】:

如果这是一个不太复杂的问题,我会完全支持将这个问题作为一个副本关闭,但正如我对这个问题的评论所说,它有点复杂。

对于初学者,您绝对应该阅读异步函数以及如何使用它们的响应。接下来,您通常应该尽量避免在循环内使用异步函数,因为它们可能难以预测和控制。幸运的是,有一些方法可以让异步函数表现得更加同步。

注意以下几点:

async formData(): Promise<void> {
  for (const id of Object.keys(this.cols)) {
    let p= cols[id];
    switch (p.name) {
      case 'a':
      this.temp.name= this.addValue(m, p);
        break;
      case 'b':
        let idx = 1;
        let surname = await this.getValue(idx);
        break;
    }
  }
  this.data.push(this.temp);
});

getValue(id: string): Promise<string> {
    return new Promise(resolve => {
        let url = this.baseUrl + '/streams/' + id+ '/data?';
        url += 'from=' + from + '&';
        url += 'to=' + to;
        this.http.get(url).map(r => r.json()).subscribe((response: any) => {
            if (response.data.values[0] !== null && response.data.values[0] !== undefined) {
                resolve(response.data.values[0]);
            }
        }, (error: any) => {
            resolve(null);
        });
    });
}

您对getValue 的调用是异步调用,因为它需要延迟(对服务器的调用)才能返回值。我已将其包装在 Promise 中,因为您希望订阅的成功和错误路径都返回一个值。

如果我们用async 关键字标记formData 方法,我们现在可以在方法中使用await 关键字。这将导致方法流在控制继续之前等待来自getValue 承诺的返回。

Side-not:通过使用异步标记 formData 方法,即使您没有直接从该方法返回任何内容,它也会使该方法的返回类型为 Promise

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    相关资源
    最近更新 更多