gpt4 book ai didi

javascript - 映射 vs concatMap

转载 作者:数据小太阳 更新时间:2023-10-29 06:09:39 25 4
gpt4 key购买 nike

我一直没能找到这个问题的答案,但是 concat map 之间有什么区别?和 map ?具体来说,我有一个让我很困惑的例子:

const domainsObservable = this.auth.getAuthDomains()
.shareReplay()
.concatMap((authDomains) => authDomains.map((domain) => this.toDomain(domain, connectionsObservable)))
.filter((authDomain) => this.isValidDomain(authDomain))
.toArray();

这是从服务 getAuthDomains() 调用一个方法,该方法刚刚返回一个包含 3 个域的数组。当我使用上面的实现时,我最终得到了一个包含 4 个数组的数组,每个数组都有一个包含 3 个域的数组。不知何故,它使响应中的数据量翻了两番。

然后我切换到以下实现:

const domainsObservable = this.auth.getAuthDomains()
.shareReplay()
.map(authDomains => authDomains.map(domain => this.toDomain(domain, connectionsObservable)))
.map(authDomains => authDomains.filter(domain => this.isValidDomain(domain)));

这正是我所需要的——一个被正确过滤的数组。

那么为什么切换到 map 会显着改变结果?我的操作顺序重要吗?

谢谢

最佳答案

简单的说两个操作符做了以下事情:

  • map() - 将每个值转换到一个不同的值中,该值在链中传播得更远:

    .map(v => v * 2)

    这与Array.map()基本相同.

  • concatMap() - 将每个值转换到一个 Observable 中并订阅它。运算符总是只订阅一个内部 Observable,所以如果源 Observable 发射值更快,它们就会被缓冲在 concatMap() 中。 :

    .concatMap(v => Observable.of(v * 2))

    ...或者通常在 Angular 中你会做这样的事情:

    .concatMap(v => this.http.get(`whatever/${v}`))

但是有趣的部分来了。在订阅内部 Observables(从投影函数等返回的 Observables)的 RxJS 5 操作符中,实际上期望所谓的“可观察输入”。这意味着您可以自由交换 Observables、Promises、类似 Observables 的对象……以及 JavaScript 数组。

在内部它是使用 subscribeToResult 实现的功能。请注意,如果您向它传递一个数组,它会迭代它并分别发出每个值:https://github.com/ReactiveX/rxjs/blob/master/src/internal/util/subscribeToResult.ts#L17

这意味着您可以使用 concatMap()将数组“解包”为单个发射。例如:

Observable.of(42)
.concatMap(v => [1, 2, 3])
.subscribe(console.log)

这将打印数字:

1
2
3

另一方面,如果您只使用 map它只会进一步传递数组:

Observable.of(42)
.map(v => [1, 2, 3])
.subscribe(console.log)

这将打印数字:

[1,2,3]

所以 concatMap有时仅用于解压缩来自源 Observable 的数组 concatMap(array => array)这正是您的代码中发生的事情。

哪个更好,就看你自己了。通常执行像 map 这样的简单操作会更容易。或 filter出于性能原因,在 Array 对象本身上而不是在 Rx 链中解包和处理。

关于javascript - 映射 vs concatMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48471872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com