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

异步搜索请求提前显示无结果,如何判断所有异步调用完成?

解决方案

核心思路是分离“实时更新结果”和“最终无结果判断”:每个异步请求完成后立即更新页面数据,同时跟踪所有请求的完成状态,只有当所有请求都结束且总结果数为0时,才显示“未找到结果”。

步骤1:调整状态变量

新增两个职责明确的状态变量,替代原有的isBusy:

// 标记是否还有请求在处理中
isLoading = false;
// 标记所有请求完成后是否无任何结果
hasNoResults = false;

步骤2:改造loadResults方法

利用RxJS的forkJoin监听所有请求完成,同时用tap操作符在每个请求完成时实时更新数据:

private loadResults(): void {
  if (!this.query || !this.selectedOperatingCompanyIds) {
    return;
  }

  // 初始化状态与结果数据
  this.isLoading = true;
  this.hasNoResults = false;
  this.results = 0;
  this.freelancers = [];
  this.assignments = [];
  this.principals = [];
  this.managers = [];
  this.bills = [];
  this.users = [];
  this.intermediaries = [];
  this.operatingCompanyUsers = [];
  this.principalUsers = [];
  this.intermediaryUsers = [];

  // 封装所有搜索请求,每个请求完成时实时更新对应数据
  const requests = [
    this.repository.searchFreelancers(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.freelancers = model;
        this.results += model.length;
      })
    ),
    this.repository.searchAssignments(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.assignments = model;
        this.results += model.length;
      })
    ),
    this.repository.searchPrincipals(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.principals = model;
        this.results += model.length;
      })
    ),
    this.repository.searchManagers(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.managers = model;
        this.results += model.length;
      })
    ),
    this.repository.searchBills(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.bills = model;
        this.results += model.length;
      })
    ),
    this.repository.searchUsers(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.users = model;
        this.results += model.length;
        this.principalUsers = model.filter(u => u.roleId == 2);
        this.intermediaryUsers = model.filter(u => u.roleId == 7);
      })
    ),
    this.repository.searchIntermediaries(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.intermediaries = model;
        this.results += model.length;
      })
    ),
    this.repository.searchOperatingCompanyUsers(this.query, this.selectedOperatingCompanyIds).pipe(
      tap(model => {
        this.operatingCompanyUsers = model;
        this.results += model.length;
      })
    )
  ];

  // 监听所有请求完成事件
  forkJoin(requests).subscribe({
    complete: () => {
      this.isLoading = false;
      // 所有请求完成后才判断是否无结果
      this.hasNoResults = this.results === 0;
    },
    error: () => {
      // 处理请求错误,标记加载结束
      this.isLoading = false;
    }
  });
}

步骤3:调整页面模板逻辑

根据新状态变量控制页面显示:

<!-- 加载中状态 -->
<div *ngIf="isLoading">加载中...</div>

<!-- 无结果状态(仅所有请求完成后显示) -->
<div *ngIf="!isLoading && hasNoResults">未找到结果</div>

<!-- 结果列表 -->
<div *ngIf="!isLoading && !hasNoResults">
  <div *ngIf="freelancers.length">自由职业者:{{ freelancers.length }}条</div>
  <div *ngIf="assignments.length">任务:{{ assignments.length }}条</div>
  <div *ngIf="principals.length">委托人:{{ principals.length }}条</div>
  <!-- 其他结果模块依次类推 -->
</div>

关键说明

  • forkJoin会等待所有传入的Observable完成后才触发回调,确保我们在所有搜索请求结束后才判断是否无结果。
  • tap操作符允许每个请求完成时立即更新页面数据,满足“尽快展示已有结果”的需求。
  • 拆分isLoading和hasNoResults变量,彻底避免了“请求未完成就误判无结果”的视觉bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:38:17