含Observable的布尔类型方法未执行subscribe逻辑就提前返回如何解决
问题原因
这是典型的异步执行顺序问题:Angular HttpClient 发起的请求是异步非阻塞操作,你调用subscribe注册回调后,JS引擎不会等待回调执行,会直接继续运行后续代码,所以return test语句会在请求的success/error/complete回调触发前就执行,此时test还没被赋值,自然返回undefined。
解决方案
共有两种常用的实现方式,都符合JS异步编程规范,不会阻塞主线程:
方案1:返回Observable,调用方订阅处理
service.ts中不直接订阅请求,把加工后的Observable直接返回给调用方:
// 注意要先导入需要的rxjs操作符 import { map, catchError } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; postFiltersAndSearch(param: someType) : Observable<boolean>{ //this.bsSearchFilter.next(param) return this.http.post<any[]>(environment.ApiUrl + 'controller/method/', param,this.tokenService.addCors()).pipe( map(x => { if(x.length==0){ //do something... } //this.bsSearchResult.next(x) return true; }), catchError(error => { console.log(error) return of(false) }) ) }
component.ts中订阅获取结果:
this.searchService.postFiltersAndSearch(someParam).subscribe(result => { // 此处拿到的result就是布尔类型的返回值,后续逻辑都在这里写 console.log(result) })
方案2:转为Promise用async/await语法
如果偏好同步写法,可以把Observable转为Promise,配合async/await实现异步逻辑同步化写法:service.ts修改如下:
async postFiltersAndSearch(param: someType) : Promise<boolean>{ //this.bsSearchFilter.next(param) try { const x = await this.http.post<any[]>(environment.ApiUrl + 'controller/method/', param,this.tokenService.addCors()).toPromise() if(x.length==0){ //do something... } //this.bsSearchResult.next(x) return true } catch(error) { console.log(error) return false } }
component.ts调用时需要用await接收:
// 注意调用该方法的父函数需要加async修饰 async yourComponentMethod() { let result = await this.searchService.postFiltersAndSearch(someParam) // 此处可以直接使用result的值 console.log(result) }
注意:不要尝试用循环、定时器等方式强制阻塞主线程等待请求返回,JavaScript是单线程运行,阻塞会导致整个页面失去响应,上述两种是唯一合规的解决方案。
内容的提问来源于stack exchange,提问作者MarloIsh
相关产品推荐
相关产品推荐

