Angular:ng-container未显示问题求助(Observable已有值)
你的问题出在**map操作符的错误使用**上:
你用了map(async ...),这会让obs$变成一个发射Promise对象的Observable(类型是Observable<Promise<SomeClass | null>>),而不是直接发射Promise最终resolve结果的Observable。
虽然Angular的async管道支持处理Promise,但这种写法会导致逻辑混乱:当obs2$发射值时,obs$会立即抛出一个Promise实例,async管道会认为这个Promise是“存在的”,但如果这个Promise最终resolve成null,*ngIf的条件就会变为false,从而显示模板。更关键的是,这种写法没有正确把异步操作的结果整合到Observable流中。
正确写法:用switchMap替代map处理异步操作
switchMap是RxJS中专门用来处理**异步操作(比如Promise)**的操作符,它会自动把Promise转换成Observable,让obs$直接发射最终的结果(类型变为Observable<SomeClass | null>):
obs$: Observable<SomeClass | null> = this.obs2$.pipe( switchMap(async (foo: SomeOtherClass | null) => { if (!foo) { return null; } const { id } = foo; const bar = await this.someService.getBarById(id); return bar; }) );
或者,你也可以用from操作符把Promise转换成Observable,写法更符合RxJS的风格:
import { from, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; // ... obs$: Observable<SomeClass | null> = this.obs2$.pipe( switchMap((foo: SomeOtherClass | null) => { if (!foo) { return of(null); // 直接返回null的Observable } const { id } = foo; return from(this.someService.getBarById(id)); // 将Promise转为Observable }) );
为什么原来的写法不生效?
你说订阅obs$后看到“有值”,其实你看到的是Promise对象本身,而不是Promise最终resolve的结果。async管道虽然能处理Promise,但你的map写法让obs$的流里充满了Promise实例,而不是你需要的业务数据。换成switchMap后,obs$会直接发射someService.getBarById返回的最终结果,*ngIf就能正确根据结果是否为null来切换显示内容了。
内容的提问来源于stack exchange,提问作者Platus

