Angular 5中Observable.map内使用setTimeout的返回类型问题
解决Observable.map中异步等待后返回值的类型错误问题
你遇到的问题核心在于**map操作符是用来同步转换值的**,而你把返回逻辑放在了setTimeout的异步回调里——这部分代码执行的时候,map早就已经完成了它的执行流程,根本捕获不到你在回调里的return值,所以整个map的返回类型变成了void,和你声明的Observable<TSUser | undefined>类型不匹配,这就是TS2322错误的根源。
要在RxJS流里处理异步等待逻辑,你需要用高阶映射操作符(比如switchMap、concatMap)配合RxJS的异步工具(比如timer)来实现,而不是原生的setTimeout。下面是修改后的代码:
首先确保你导入了需要的RxJS工具和操作符:
import { timer } from 'rxjs'; import { switchMap, map } from 'rxjs/operators';
然后修改你的loginRequest方法:
public loginRequest(userCredentials: any): Observable<TSUser | undefined> { return this.http.post<TSUser>(this.serviceURL + '/login', userCredentials).pipe( switchMap((response: any) => { // 用timer创建一个300ms后触发的Observable return timer(300).pipe( map(() => { this.initWithCookie(); return this.principal; }) ); }) ); }
为什么这样能解决问题?
switchMap会接收上游http请求返回的结果,然后把它转换成一个新的Observable(这里就是timer(300)返回的流)timer(300)会在300毫秒后发出一个值,触发后续的map操作- 在这个
map里,你可以同步执行initWithCookie并返回this.principal,整个流的返回类型就和你声明的Observable<TSUser | undefined>完全匹配了
额外提醒:如果你的initWithCookie本身是异步操作(比如返回Promise或Observable),那你还需要把它也包装进流里,比如用from把Promise转成Observable,再用switchMap串联,但从你的代码来看,它应该是同步的,所以上面的写法就足够了。
内容的提问来源于stack exchange,提问作者Gatschet
相关产品推荐
相关产品推荐

