Angular中如何等待Observable类型接口返回数据后再执行后续逻辑
问题解决方法
核心原因
你遇到的问题本质是http.post返回的是异步Observable对象,subscribe回调会在网络请求完成后才执行,getSqlResult不会等待回调执行就直接返回了初始的空对象,因此拿不到接口返回的有效数据。
方案1:使用Observable订阅(Angular推荐写法)
我们调整方法逻辑,让getSqlResult直接返回Observable,后续逻辑放到订阅回调里执行即可保证数据加载完成后再运行:
- 首先导入rxjs的map操作符:
import { map } from 'rxjs/operators';
- 修改
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) ); }
- 修改
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实现等待逻辑:
- 如果是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; }
- 修改
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
相关产品推荐
相关产品推荐

