在Observable中调用Promise:如何让getEmployees无需异步即可调用getToken
实现思路与问题解决
现有代码的问题
你的写法无法运行的核心原因是同步代码执行顺序早于异步回调:
- 调用
subscribe监听token返回属于异步操作,JS主线程不会等待回调执行,会直接往下运行创建HttpHeaders的代码,此时token还未被赋值,值为undefined subscribe方法的返回值是Subscription订阅对象,不是异步返回的token值,直接传入header配置完全无效- 不需要手动包装新的Promise,RxJS提供的
from操作符可以直接把Promise实例转换成Observable
可行实现方案
你不需要修改getEmployees的返回类型,也不需要将其改为异步函数,只需要用RxJS的switchMap操作符把「获取token的异步流」和「发起http请求的流」串接起来即可,保证请求发起时已经拿到有效token:
首先导入需要的依赖:
import { from, switchMap } from 'rxjs';
修改后的getEmployees代码:
getEmployees(): Observable < EmpleadoTarjeta[] > { // 把getToken返回的Promise直接转为Observable return from(this.getToken()).pipe( // 等token获取成功后,切换到http请求流 switchMap((tokenUser: string) => { // 此时已经拿到有效token,再构造请求头 const httpHeaders: HttpHeaders = new HttpHeaders({ tokenJPA: tokenUser, }); // 发起原有http请求 return this._httpClient.get<EmpleadoTarjeta[]>('你的API地址', { headers: httpHeaders }); }), // 原有数据转换和更新逻辑保持不变 map(response => response.map(item => new EmpleadoTarjeta(item))), tap((empleados) => { this._empleados.next(empleados); }) ); }
方案说明
- 完全保留了
getEmployees的原函数签名,返回值仍然是Observable<EmpleadoTarjeta[]>,不需要声明为async函数 - 通过RxJS操作符链式调用,天然保证了http请求一定在token获取成功之后才发起,请求头的token值是有效的
- 异常可以直接在调用
getEmployees的订阅端通过error回调捕获,也可以根据需要在流中添加catchError操作符处理token获取失败、请求出错等场景
内容的提问来源于stack exchange,提问作者raulabad
相关产品推荐
相关产品推荐

