rxjs - 如果身份传递了,为什么 mergeMap 会扁平化?

标签 rxjs

我试图理解为什么 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运算符,例如 concatMapswitchMap运算符,采用 (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/

相关文章:

angular - 使用 Observables 在 Angular 中一个接一个地调用两个服务

Angular:异步管道在与 View 交互之前不更新 View

node.js - RxJS 结果与 switchMap 和 mergeMap

javascript - RxJS Observable :'Skip is not a function'(或任何其他函数)

angular - 在发送其他请求之前,不会重复/执行 http GET

javascript - RxJS:模拟 Angulars @Input() 绑定(bind)?

angular - 如何格式化和显示从 AngularFire 返回的 Firestore 数据?

RxJS Buffer,如何将多次单击事件分组为流

javascript - Debounce Rx.Observable 并忽略之间发出的值

Angular RxJS - 取消订阅 mergeMap?