RXJS中forkJoin是否支持传入Observable<[]>?附使用场景验证
嘿,这个问题问得很到位!先直接给你答案:RxJS的forkJoin确实支持传入Observable<[]>类型的参数,但这里有个关键的行为差异需要注意,和你用它实现类似Promise.all的预期可能不一样。
我们先拆解下你的代码逻辑:
你的变量d是通过from(arr).pipe(mergeMap(...), toArray())生成的,它本质上是一个只会发出一次完整数组结果的Observable——等所有myPromise(f)处理完成后,它会把所有结果打包成一个数组发射出来,然后完成。
当你把这个d传给forkJoin时,forkJoin的行为是:等待这个Observable完成,然后把它的最后一个发射值(也就是那个完整数组)包装成一个新数组返回。举个例子,如果d最终发出[result1, result2, result3, result4, result5],那么forkJoin(d)订阅后会输出[[result1, result2, result3, result4, result5]](一个嵌套数组),而不是你可能期望的直接输出[result1, result2,...]。
如果你的目标是完全对齐Promise.all的效果(并行处理多个异步任务,最终收集所有结果成一个平级数组),其实更直接的写法是把数组转换成Observable的数组,再传给forkJoin:
let arr: Array<Number> = [1, 2, 3, 4, 5]; // 把每个数字转换成对应的Observable/Promise,得到Observable数组 const obsCollection = arr.map(num => myPromise(num)); const example = forkJoin(obsCollection); const subscribe = example.subscribe(val => console.log(val)); // 最终输出:[result1, result2, result3, result4, result5]
再明确下forkJoin的几种常见传参行为:
- 传入Observable数组:
forkJoin([obs1$, obs2$, obs3$])→ 等待所有Observable完成,收集每个Observable的最后值,返回一个平级结果数组 - 传入单个Observable(包括发出数组的
Observable<[]>):forkJoin(obs$)→ 等待这个Observable完成,把它的最后值包装成数组返回(比如obs$发[a,b],就返回[[a,b]])
所以你的代码能正常运行是因为forkJoin支持这种传参,但从实现Promise.all的角度来说,直接传Observable数组是更贴合预期的写法。
内容的提问来源于stack exchange,提问作者Royi Namir

