【问题标题】:How can I have an observable call another one based on the result?如何根据结果进行可观察的调用?
【发布时间】:2020-12-29 17:04:52
【问题描述】:

情况:

我有一个 http 请求,一旦我得到它,我需要发出另一个请求。但是,我提出的第二个请求取决于第一个请求的结果。例如,我的第一个请求要么返回通过,要么返回失败,如果返回通过,我想调用 apiPass,如果失败,我想返回不同的 Observable。

我知道如果我在第一个电话之后只有一个电话,我可以使用类似 mergemap 的东西并编写类似的东西

return this.http.post<{id:string, resPass:boolean}>(this.urlFirst, bodyObject)
    .pipe(mergeMap(this.http.get<any>(this.passUrl)));

但我的情况不同——我想使用 resPass 来知道我是否确实应该调用 pass Api,或者我是否应该执行失败逻辑(它也应该返回一个 Observable,只是一个不同的)。如果第一个调用参数通过,我如何在没有不必要订阅的情况下映射到一个 Observable (http.get(this.passUrl)),如果参数失败,如何映射到另一个 (otherObservable)?

在这两种情况下,我的第一次调用都应该返回 http code 200 ,所以这也不是 http 失败的问题。

有什么线索吗?

【问题讨论】:

    标签: angular http rxjs rxjs-pipeable-operators


    【解决方案1】:

    如果我理解你的问题是正确的,我会尝试这些方面的东西

    return this.http.post<{id:string, resPass:boolean}>(this.urlFirst, bodyObject)
     .pipe(
         // concatMap is the preferred operator for typical http operations, see below for more details
         concatMap(({id:string, resPass:boolean}) => resPass ? 
                           this.http.get<any>(this.passUrl) : 
                           otherObservable)
     );
    

    在处理 http 异步请求时,通常最好使用 concatMap 运算符,因为这样的运算符确保我们在继续其他与 observable 相关的异步操作之前收到来自 http 的响应,例如在这种情况下,我们可能会在第一个返回后进行另一个 http 调用。

    concatMap 中,我们使用解构定义预期作为第一次调用返回的值的结构(即使用这种形式({id:string, resPass:boolean})),然后根据ressPass 的值,我们要么执行第二次http 调用或者我们返回otherObservable,假设它之前已经在某个地方定义过。

    您可能会通过 http looking at this article 获得有关 rxjs 典型使用模式的一些启发。

    【讨论】:

    • concatMap、exhaustMap、switchMap和mergeMap的使用取决于你做的http请求的类型。对于这样的获取,取决于背后的应用程序,switchMap 可能更好。
    • @Jean-Xavier Raynaud 我同意你的看法,这取决于。同时,我对 concatMap 作为 http 调用的正确操作符的评论源于我的经验以及 rxjs 的主要贡献者 Ben LEsh 的评论,您可以在 this video 的开头收听。 POST 调用对concatMap 的偏好更强,因为它可以确保您在执行任何操作之前收到来自每个调用的响应,这有助于避免同时进行多个 POST。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    相关资源
    最近更新 更多