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

Angular中如何等待Observable类型接口返回数据后再执行后续逻辑

问题解决方法

核心原因

你遇到的问题本质是http.post返回的是异步Observable对象,subscribe回调会在网络请求完成后才执行,getSqlResult不会等待回调执行就直接返回了初始的空对象,因此拿不到接口返回的有效数据。

方案1:使用Observable订阅(Angular推荐写法)

我们调整方法逻辑,让getSqlResult直接返回Observable,后续逻辑放到订阅回调里执行即可保证数据加载完成后再运行:

  1. 首先导入rxjs的map操作符:
import { map } from 'rxjs/operators';
  1. 修改getSqlResult方法:
getSqlResult(): Observable<sqlResultModel> {
  this.sqlModel.dbSourceId=1;
  this.sqlModel.limitperPage=1;
  this.sqlModel.pageNum=1;
  this.sqlModel.query="SELECT [CODE],[DEFINITION_] FROM [TEST].[dbo].[PRODUCTS]";
  // 直接返回请求对象,用map提取需要的Result字段
  return this.sqlService.getList(this.sqlModel).pipe(
    map(i => i.Result)
  );
}
  1. 修改openInputPopup方法,在订阅回调里执行弹窗逻辑:
openInputPopup():void{
  this.getSqlResult().subscribe(resModel => {
    // 此处代码会等接口请求成功后才执行
    console.log('res',resModel);
    const modal = this.inputPopup.create({
      nzTitle: 'Component Settings',
      nzStyle:{'top':'20px', 'width':'60%'},
      nzContent: FormPopupModalComponent,
      nzViewContainerRef: this.viewContainerRef,
      nzComponentParams: {   
        sqlResModel:resModel 
      },
      nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))      
    });
    modal.afterClose.subscribe(a=>{
      var el = document.getElementById('popDeneme');
      this.popValue = modal.componentInstance.inputId;
    });
  })
}

方案2:转Promise用async/await(更符合新手的同步直觉)

如果你更习惯类似同步代码的等待写法,可以把Observable转成Promise,用async/await实现等待逻辑:

  1. 如果是Angular 12以下版本,直接用toPromise:
// 修改getSqlResult为async方法,返回Promise
async getSqlResult(): Promise<sqlResultModel> {
  this.sqlModel.dbSourceId=1;
  this.sqlModel.limitperPage=1;
  this.sqlModel.pageNum=1;
  this.sqlModel.query="SELECT [CODE],[DEFINITION_] FROM [TEST].[dbo].[PRODUCTS]";
  const result = await this.sqlService.getList(this.sqlModel).toPromise();
  return result.Result;
}

如果是Angular12+版本,toPromise已废弃,改用firstValueFrom:

// 先导入firstValueFrom
import { firstValueFrom } from 'rxjs';

async getSqlResult(): Promise<sqlResultModel> {
  this.sqlModel.dbSourceId=1;
  this.sqlModel.limitperPage=1;
  this.sqlModel.pageNum=1;
  this.sqlModel.query="SELECT [CODE],[DEFINITION_] FROM [TEST].[dbo].[PRODUCTS]";
  const result = await firstValueFrom(this.sqlService.getList(this.sqlModel));
  return result.Result;
}
  1. 修改openInputPopup为async方法,等待结果返回:
async openInputPopup(): Promise<void>{
  // 等待接口请求完成拿到结果后再执行后续代码
  const resModel = await this.getSqlResult();
  console.log('res',resModel);
  const modal = this.inputPopup.create({
    nzTitle: 'Component Settings',
    nzStyle:{'top':'20px', 'width':'60%'},
    nzContent: FormPopupModalComponent,
    nzViewContainerRef: this.viewContainerRef,
    nzComponentParams: {   
      sqlResModel:resModel 
    },
    nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))      
  });
  modal.afterClose.subscribe(a=>{
    var el = document.getElementById('popDeneme');
    this.popValue = modal.componentInstance.inputId;
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 13:54:00