在 Angular 7 中,为啥即使只订阅一次 HttpClient.post 也会执行两次?

Posted

技术标签:

【中文标题】在 Angular 7 中,为啥即使只订阅一次 HttpClient.post 也会执行两次?【英文标题】:In Angular 7, why HttpClient.post is getting executed twice even if subscribed only once?在 Angular 7 中,为什么即使只订阅一次 HttpClient.post 也会执行两次? 【发布时间】:2019-10-17 05:08:54 【问题描述】:

只有在我从 HttpClient.post 订阅了这个 observable 之后。但是,发布请求被执行了两次,因此两次添加了相同的记录。请注意,所有调试日志语句都显示,只有来自订阅功能的成功响应被打印(并执行)两次。

  addTemplate(template) 
      console.log('In addTemplate');
      let authHeaders = new HttpHeaders();
      authHeaders = authHeaders.set('Authorization', 'Bearer ' + localStorage.getItem('id_token'));
      authHeaders = authHeaders.set('Content-Type', 'application/json');
      const httpOptions = 
        headers: authHeaders,
        observe: 'body' as 'body',
        responseType: 'json' as 'json'
      ;
      console.log('^^^^^ addTemplate  Service Header  = ', httpOptions);

      this.httpClient.post<any>(this.constants.URL + 'addTemplate', JSON.stringify(template),
        headers: authHeaders).pipe().subscribe(
        (response) =>   console.log ('Added Template Successfully -->', response),
        (error) =>  console.error('Got an Error while adding Template ->', error) 
      );
   

上面的函数是从这里调用的:

 saveTemplate()
      const saveTemplate : ITemplate = Object.assign(, this.templateForm.value);
      console.log('Adding new Template with name -->', saveTemplate.name);
      this.templateService.addTemplate(saveTemplate);
      

这是浏览器控制台的图片:

这是浏览器网络标签的图片:

如您所见,对 addTemplate REST API 的 HttpClient.post 调用被调用了两次。即使 post call 只订阅了一次,并且没有其他地方可以调用它。通话记录

  console.log('^^^^^ addTemplate  Service Header  = ', httpOptions);

在服务中的addTemplate函数执行一次但是log(response) => console.log('Added Template Successful-->', response),执行了两次。

我确实尝试更改对 httpClient.post 的调用以使用 share() 和 publishLast().refCount() 但没有任何效果。可能是我做的不对。

将 Angular 7.2 与 rxjs 6.5.2 和 rxjs/compat 一起使用(是的,我确实有一些遗留代码需要升级到最新版本)

【问题讨论】:

你确定这两个请求是一样的吗?也许第一个是类型 OPTIONS 是的,两者都是相同的请求。这就是为什么在后端添加了两次相同的记录(通过 REST API) 谁在使用saveTemplate() 方法?点击事件? 这只会触发一次。如您所见,addTemplate 服务函数中的“^^^^^ addTemplate Service Header =”消息仅打印一次,而“已成功添加模板”打印两次。 ).pipe().subscribe(把不需要的pipe()去掉再试一次 【参考方案1】:

这是我的错。该表单正在调用 saveTemplate() 以及按钮...所以它被调用了两次。

<form [formGroup]="templateForm" autocomplete="off" novalidate (ngSubmit)="saveTemplate()">

按钮:

          <button mat-button mat-raised-button color="primary"
              type="submit" (click)="saveTemplate()" [disabled]="templateForm.pristine">Save

感谢@CaptainFindus、@Alexander Staroselsky 和大家的帮助

【讨论】:

以上是关于在 Angular 7 中,为啥即使只订阅一次 HttpClient.post 也会执行两次?的主要内容,如果未能解决你的问题,请参考以下文章

为啥订阅在 Angular 中没有 Observable 的情况下工作

为啥我应该在 Angular 订阅中使用 select 和管道?

为啥一个成员函数只存在一次,甚至在一个包含多个的 .h 文件中定义? [复制]

将两个异步订阅放在一个 Angular *ngIf 语句中

RxJava 作为事件总线被多次调用,即使只触发一次

Angular中利用rxjs库的Subject多播解决在第一次订阅时进行初始化操作(如第一次订阅时从服务器获取数据)