RxJS:如何让getStrings函数返回Observable<string>[]类型?
首先咱们得先理清你遇到的类型矛盾:你的getStrings函数声明要返回Observable<string>[](一个由Observable<string>组成的数组),但当前代码实际返回的是Observable<Observable<string>[]>(一个Observable,它发出的值是Observable<string>[]类型的数组)——这俩完全不是一回事,所以TypeScript才会抛出类型错误。
下面分两种情况给你对应解决方案,覆盖你可能的真实需求:
情况1:确实需要返回Observable<string>[]类型(数组)
如果你的目标就是得到一个包含多个Observable<string>的数组,那不能直接从numbers$的pipe链里返回结果(因为pipe会把所有输出都包装成Observable)。你需要先获取numbers$发出的实际值,再生成目标数组。这里可以用RxJS 7+推荐的firstValueFrom把Observable转成Promise,结合async/await实现:
import { of, Observable, firstValueFrom } from 'rxjs'; const numbers$: Observable<number[]> = of([1,2,3]); const strings: string[] = ["a","b"]; async function getStrings(): Promise<Observable<string>[]> { // 等待numbers$发出第一个值 const numbers = await firstValueFrom(numbers$); // 根据strings数组生成对应的Observable数组 return strings.map(s => of(s)); } // 使用示例 getStrings().then(obsArray => { obsArray.forEach(obs => obs.subscribe(str => console.log(str))); });
注:如果用的是RxJS 6及更早版本,可以用
toPromise()代替firstValueFrom,不过toPromise()已经被官方弃用,建议升级RxJS版本或者改用新API。
情况2:实际需要的是Observable<string[]>或Observable<string>
大概率你可能对返回类型有误解——如果你的目标是创建一个能发出字符串数组的Observable,或者能逐个发出字符串的Observable,那调整起来会更简单:
子情况2.1:返回Observable<string[]>(发出字符串数组的Observable)
直接在map操作符里返回strings数组即可,不需要把每个字符串包装成Observable:
import { of, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; const numbers$: Observable<number[]> = of([1,2,3]); const strings: string[] = ["a","b"]; function getStrings(): Observable<string[]> { return numbers$.pipe( map((numbers: number[]) => { // 直接返回strings数组,流会把这个数组作为值发出 return strings; }) ); } getStrings().subscribe(strArray => console.log(strArray)); // 输出 ["a", "b"]
子情况2.2:返回Observable<string>(逐个发出字符串的Observable)
如果想让流逐个发出strings里的每个字符串,可以用mergeAll(或concatAll/switchAll,根据你的订阅需求选择)把Observable数组展平:
import { of, Observable } from 'rxjs'; import { map, mergeAll } from 'rxjs/operators'; const numbers$: Observable<number[]> = of([1,2,3]); const strings: string[] = ["a","b"]; function getStrings(): Observable<string> { return numbers$.pipe( map((numbers: number[]) => strings.map(s => of(s))), mergeAll() // 把Observable数组展平成单个Observable,依次发出每个字符串 ); } getStrings().subscribe(str => console.log(str)); // 依次输出 "a", "b"
快速区分类型差异
Observable<string>[]:数组类型,数组里的每个元素是ObservableObservable<Observable<string>[]>:Observable类型,它会发出一个由Observable组成的数组Observable<string[]>:Observable类型,它会发出一个字符串数组Observable<string>:Observable类型,它会逐个发出字符串
你可以根据自己的实际业务场景选择对应的方案~
内容的提问来源于stack exchange,提问作者Aamir

