Angular 6 Async-await 不适用于 http 请求

Posted

技术标签:

【中文标题】Angular 6 Async-await 不适用于 http 请求【英文标题】:Angular 6 Async-await not working on http request 【发布时间】:2019-05-08 10:11:49 【问题描述】:

您好,我使用 Angular 6 使用以下代码调用 rest api。我正在尝试使代码与 async-await 函数同步。但是缺少一些东西

async save() 

    if (this.changedRecords.length !== 0) 
          this.post('/api/devices/update-devices', this.changedRecords).
          then(x =>  console.log("change"); console.log(`Resolved: $x`) );
    
    if (this.newRecords.length !== 0) 
          this.post('/api/devices/new-devices', this.newRecords).
            then(x =>  console.log("new"); console.log(`Resolved: $x`) );
    
    if (this.deletedRecords != null) 
      this.post('/api/devices/delete-devices', this.deletedRecords).
        then(x =>  console.log("deleted"); console.log(`Resolved: $x`) );
    



  async post(url: string, list: DboDevice[]) 
    var result;
    if (list.length !== 0) 
      await this.http.post(url, list).subscribe(result => 
        result = true;
      , error => 
        console.error(error);
        result = false;
      );
    
    else 
      result = true;
    
    return result;
  

但是,当我运行此代码时,这些值在控制台中返回为“已解决:未定义”。这让我相信 await 不会停止 post() 函数中的程序。我在这里做错了什么?

【问题讨论】:

【参考方案1】:

Angular 的 this.http.post 返回一个 RxJS Observable。然后调用 this.http.post(...).subscribe(...) 返回 RxJS Subscription 对象。所以它们都没有返回 Promise,所以你不能将它们与 await 一起使用。

如果您希望能够将 await 与 Observables 一起使用,则必须使用 toPromise() 而不是 subscribe(),它返回一个由该 Observable 发出的第一个值解析的 Promise(它在内部调用 subscribe为你,并用Promise 对象包装它)。

await this.http.post(...).toPromise(value => 
  ...
);

https://github.com/ReactiveX/rxjs/blob/master/src/internal/Observable.ts#L342-L354

【讨论】:

感谢马丁非常有用的信息。这确实是问题所在,我现在就可以开始工作了。 对于在此之后也遇到尝试输出错误的问题的任何人,我通过添加 .catch(error => console.log(error) );在 toPromise() 结束时

以上是关于Angular 6 Async-await 不适用于 http 请求的主要内容,如果未能解决你的问题,请参考以下文章

Angular 6 组件根据路线变化,错误:选择器“app-navbar”不匹配任何元素

async-await

在 .net 4 上使用 async-await

async-await 同时触发(等待)多个异步操作

angular-testing-library:getByRole 查询仅适用于 hidden: true 选项

将 async-await 与 node-fetch 一起使用不会将响应返回给调用方法