angular - RXJS 如何在另一个中使用一个 observable 的结果(然后将这两个结果一起处理)

标签 angular rxjs rxjs6 rxjs-pipeable-operators

使用 RxJs 时一个非常常见的问题似乎是希望一个或多个 observables 的结果然后在后续的中使用它们。

例如在伪代码中(这不是故意的 rx 或有效的 js 语法)

var someResult = $observable-A; // wait to complete
var finalResult = $observable-B(someResult.aValueINeed);

这可以以一种丑陋的方式完成,您可以订阅两者并在另一个内部调用一个..但是,这非常困惑并且不能为您提供很大的灵活性。

例如(真正的语法)
$observable-A.subscribe(resultA => { 
    $observable-B(resultA.aValueINeed)
        .subscribe(resultB => { 
            console.log('After everything completes: ', resultB); 
        }
}

这也意味着当您完成两个可观察对象时,没有其他任何东西可以轻松消耗此流。

我的特定用例需要以下内容:
  • 获取 $observable-A 的初始调用,因为它不需要其他任何东西(这是一个基本的 http GET 调用)
  • 对另一个服务的 http GET 调用需要来自 $observable-A 的数据,它返回 $observable-B
  • 使用两个可观察结果 (A + B) 为我的服务(在我的情况下,Angular 服务)创建一个对象以返回单个列表。

  • I also need to be able to subscribe to this function inside my service, this is why going with the subscribe method above, won't work for me.

    最佳答案

    Snorre Danielsen nailed this problem and full credit for this solution goes to him. I'd recommend having a look at this.



    rxjs 操作符的伟大之处在于它们的互操作性。您可以混合和匹配几乎所有内容以获得所需的结果。

    简而言之。这个问题的代码答案如下,我将进一步解释。
    $observable-A.pipe(
        mergeMap(resultA => {
            return combineLatest(
                of(resultA),
                $observable-B(resultA)
            )
        }),
        map(([resultA, resultB]) => {
            // you can do anything with both results here
            // we can also subscribe to this any number of times because we are doing all the processing with
            // pipes and not completing the observable
        }
    )
    

    mergeMap (或 flatMap 这是一个别名)将一个 observable 作为输入并投影它(就像一个常规的 map 函数)。这意味着我们可以使用它的结果作为 $observable-B 的输入。 .现在这非常适合您实际上只想返回第二个可观察结果。例如
    $observable-A.pipe(
        mergeMap(resultA => $observable-B(resultA)),
        map((resultB) => {
            // resultA doesn't exist here and we can only manipulate resultB
        }
    )
    
    

    现在,回到主要解决方案。 combineLatest 是这里的关键。它允许 mergeMap基本上“等待”内部可观察对象( $observable-B )完成。
    没有它,你只需要在 pipe 中向下一个 rxjs 操作符返回一个 observable。 ,这不是我们想要的(因为您希望处理 pipe 中的常规运算符函数)。

    因此,我们可以将这些新合并的 observable 带入链的下一部分并一起使用。我们使用 of()重新创建函数resultA , 如 combineLatest仅将 observables 作为输入和 resultA在这种状态下是一个完整的 observable。

    A hint: Take a look at the map(([resultA, resultB]). The reason we use this notation to refer to our variables instead of the standard map(results). Is so we can directly reference them without using results[0] for resultA or results[1] for resultB. Its just a lot easier to read this way.



    I hope this helps people out as I have yet to find a complete SO answer which covers this case. Edits are very welcome as its complicated and I'm sure its not a perfect answer.

    关于angular - RXJS 如何在另一个中使用一个 observable 的结果(然后将这两个结果一起处理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62141648/

    相关文章:

    html - 复选框检查 boolean 值是否为真与 Angular2

    Angular 4如何应用动态样式?

    ajax - Angular2 捕获请求错误

    javascript - 触发多个 Action 并等待它们解析 RxJS/Redux Observables

    rxjs - mergeMap 在 rxjs6 中抛出 'invalid object where a stream was expected' 错误

    javascript - 如何在 AngularJs2 中添加动态 formControlName

    javascript - 如何关闭点击外部的下拉菜单?

    javascript - 如何使用 Angular 5 中的异步更新输入变化时的数组?

    angular - 错误 TS2339 : Property 'combineLatest' does not exist on type 'typeof Observable'

    javascript - typescript :从扩展类调用 super 方法会产生类型错误 - (中间值)不是函数