You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API调用时正确显示与隐藏Mat Spinner?

解决API调用时Mat Spinner不生效的问题

你的问题核心确实是subscribe的异步特性导致的——你现在的代码里,this.loading = false;是同步执行的,API请求还在后台处理时,这句代码已经把loading改成false了,Spinner根本来不及显示,甚至因为请求太快出现了短暂的空白屏幕。

给你几个简便的解决方法,按优雅程度排序:

方法1:用RxJS的finalize操作符(推荐)

这个操作符会在Observable完成(不管成功还是失败)的时候执行回调,完美解决异步状态重置的问题,代码也最简洁:

this.loading = true;
this.ticketModelService.farmerList
  .pipe(finalize(() => this.loading = false)) // 请求结束(成功/失败)都会关闭loading
  .subscribe(value => {
    if (value) {
      this.farmerList = value.data;
      this.paginationNumbers = value.recordsFiltered;
    }
  });

方法2:在subscribe的回调里统一处理loading状态

如果不想用RxJS操作符,也可以把loading=false放到订阅的next和error回调里,确保无论请求结果如何都能重置状态:

this.loading = true;
this.ticketModelService.farmerList
  .subscribe({
    next: (value) => {
      if (value) {
        this.farmerList = value.data;
        this.paginationNumbers = value.recordsFiltered;
      }
      this.loading = false;
    },
    error: (err) => {
      // 这里可以加错误提示,比如给用户弹个Toast
      console.error('获取农户列表失败', err);
      this.loading = false;
    }
  });

额外解决:2毫秒空白屏幕的问题

如果API请求太快,Spinner只闪一下或者出现空白,你可以给loading加个最小显示时长(比如500毫秒),避免这种尴尬的情况:

import { timer, forkJoin } from 'rxjs';

this.loading = true;
// 强制至少显示500毫秒的loading
const minLoading$ = timer(500);
const apiRequest$ = this.ticketModelService.farmerList;

forkJoin([minLoading$, apiRequest$]).subscribe(([_, value]) => {
  if (value) {
    this.farmerList = value.data;
    this.paginationNumbers = value.recordsFiltered;
  }
  this.loading = false;
}, (err) => {
  console.error('请求失败', err);
  this.loading = false;
});

这样哪怕API请求2毫秒就完成,Spinner也会显示够500毫秒,用户体验会好很多。

内容的提问来源于stack exchange,提问作者Prashant Pimpale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:59:33