我试图理解为什么 Rxjs 的 mergeMap
在传入身份函数时会变平
of(['click', 'tap'])
.pipe(
mergeMap(_ => _),
tap(console.log) // Gets called twice, first with 'click' then with 'tap'
)
.subscribe();
而在本例中则不是:
of(['click', 'tap'])
.pipe(
mergeMap(_ => Promise.resolve(_)),
tap(console.log) // Gets called once with ['click', 'tap']
)
.subscribe();
最佳答案
mergeMap
运算符,例如 concatMap
和switchMap
运算符,采用 (value: T, index: number) => O
类型的函数作为参数,其中 O extends ObservableInput<any>
。
这与更简单的运算符不同,例如 map
,它采用 (value: T, index: number) => R
类型的函数,其中R
是函数本身返回值的类型。
这意味着您在 mergeMap
中返回的所有内容函数必须从 ObservableInput
扩展,这很简单:
type ObservableInput<T> = Observable<T> | InteropObservable<T> | AsyncIterable<T> | PromiseLike<T> | ArrayLike<T> | Iterable<T> | ReadableStreamLike<T>;
所以当你使用恒等函数返回 string[]
时, mergeMap
会将该值理解为 ArrayLike<string>
。事实上,它正在展平数组,这是可以预料的,因为它创建了 Subscription
对于 ArrayLike<string>
的每个值.
以Promise.resolve(_)
为例,它将其解释为 PromiseLike
,也就是说,它使用发出的值创建一个 promise ,该值恰好是一个数组。它变成了Promise<string[]>
进入Observable<string[]>
内部。如果运行以下代码,结果将是相同的:
of(['click', 'tap'])
.pipe(
mergeMap((x) => of(x)),
tap(console.log)
)
.subscribe();
希望对你有帮助!请参阅https://rxjs.dev/api/operators/mergeMap了解更多信息。
关于rxjs - 如果身份传递了,为什么 mergeMap 会扁平化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74813608/