TypeScript异步调用问题:等待服务响应后再打开Modal
问题描述
我用TypeScript开发时,想在函数里调用Modal弹窗,但得先调用服务从服务器验证内容,根据返回结果决定是否打开Modal。现在服务调用是异步的,导致Modal在收到服务器响应前就打开了。CheckandOpenModal函数需要等saveRecord执行完,根据返回值判断是否打开Modal,但现在服务没响应就返回,output一直是初始值0,Modal总是被调用,该怎么解决?
核心代码如下:
public output:number = 0; CheckandOpenModal() { /* do something */ this.saveRecord(); // 需等待此方法完成并返回output if (this.output == 0) { // 调用Modal窗口 const modalRef = this.modalService.open(editTableColComponent, { centered: true, scrollable: true }); } else { // 执行其他操作 } } saveRecord() { this.serv.checkTableRecord(this.objTableFields.tableNm, this.objTableFields.tableID).subscribe(data => { if (data.check.result == 1) { this.output = 1; } }); }
解决方案
方法1:让saveRecord返回Observable,在CheckandOpenModal中订阅
不要依赖全局的output变量,直接在异步回调里处理逻辑:
修改saveRecord使其返回Observable:
saveRecord(): Observable<boolean> { return this.serv.checkTableRecord(this.objTableFields.tableNm, this.objTableFields.tableID).pipe( map(data => { // 返回验证结果:result为1时返回true,否则false return data.check.result === 1; }) ); }
修改CheckandOpenModal,在订阅回调中处理弹窗逻辑:
CheckandOpenModal() { /* do something */ this.saveRecord().subscribe(isValid => { if (!isValid) { // 对应原逻辑中output==0的情况 const modalRef = this.modalService.open(editTableColComponent, { centered: true, scrollable: true }); } else { // 执行其他操作 } }); }
方法2:使用async/await(将Observable转为Promise)
如果习惯同步风格的写法,可以把Observable转为Promise,用async/await处理:
修改saveRecord为异步函数:
async saveRecord(): Promise<boolean> { const data = await this.serv.checkTableRecord(this.objTableFields.tableNm, this.objTableFields.tableID).toPromise(); return data.check.result === 1; }
修改CheckandOpenModal为async函数,等待验证结果:
async CheckandOpenModal() { /* do something */ const isValid = await this.saveRecord(); if (!isValid) { const modalRef = this.modalService.open(editTableColComponent, { centered: true, scrollable: true }); } else { // 执行其他操作 } }
关键说明
原问题的核心是异步操作的时序问题:saveRecord里的subscribe是异步回调,CheckandOpenModal中的if(this.output == 0)会在回调执行前就运行,所以output始终是初始值0。上面两种方法都是把弹窗判断逻辑放到异步操作完成后执行,避免了全局变量带来的时序错误。
内容的提问来源于stack exchange,提问作者saurav sam
相关产品推荐
相关产品推荐

