Angular中如何处理subscribe异步操作,返回正确列表数据
解决异步订阅导致的返回值为空问题
问题核心是subscribe内的代码是异步执行的:当你调用this.service.getWinServicesInfo()时,HTTP请求会在后台发起,主线程会继续执行后面的console.log(this.dataArrs)和return this.dataArrs,这时候请求还没完成,setSubscribeData还没被调用,所以数组是空的。
要让外部能拿到正确的数组,不能直接同步返回,必须利用RxJS的异步特性处理,以下是两种可行方案:
方案一:返回Observable,让调用方订阅
修改winServiceInfo函数,不再直接返回数组,而是返回处理后的Observable,把数据处理逻辑放在map操作符中:
winServiceInfo(): Observable<any[]> { this.dataArrs = []; this.winServiceURL = JSON.parse(this.WinService[0].windowsServicesInfo)["Stactuscheck"]; return this.service.getWinServicesInfo(this.winServiceURL) .pipe( catchError(this.handleError), map((data: any) => { this.setSubscribeData(data); console.log(this.dataArrs); // 此处输出Array(3) return this.dataArrs; }) ); } setSubscribeData(data): any[] { this.WinService = data.windowsServicesInfo; this.dataArrs = this.getKeyValJsonObj(); return this.dataArrs; }
调用该函数时,需要通过订阅获取结果:
this.winServiceInfo().subscribe(dataArrs => { console.log(dataArrs); // 此处输出Array(3) });
方案二:用async/await结合RxJS的firstValueFrom
将函数改为异步函数,利用firstValueFrom把Observable转为Promise,通过await等待异步结果:
import { firstValueFrom } from 'rxjs'; async winServiceInfo(): Promise<any[]> { this.dataArrs = []; this.winServiceURL = JSON.parse(this.WinService[0].windowsServicesInfo)["Stactuscheck"]; try { const data = await firstValueFrom(this.service.getWinServicesInfo(this.winServiceURL)); this.setSubscribeData(data); console.log(this.dataArrs); // 此处输出Array(3) return this.dataArrs; } catch (error) { this.handleError(error); return []; } } setSubscribeData(data): any[] { this.WinService = data.windowsServicesInfo; this.dataArrs = this.getKeyValJsonObj(); return this.dataArrs; }
调用时需要用await(调用函数也必须是async函数):
async fetchData() { const result = await this.winServiceInfo(); console.log(result); // 此处输出Array(3) }
注意:异步操作无法同步返回结果,必须通过订阅Observable或await Promise的方式等待操作完成后再获取数据。
内容的提问来源于stack exchange,提问作者Rock
相关产品推荐
相关产品推荐

