当前位置: 首页 > 知识库问答 >
问题:

Rxjs:根据可观察值,管道使用mergeMap或switchMap

司英飙
2023-03-14

我们有一个执行http请求的请求服务。所有请求都实现IRequest接口,该接口包含http方法和一个执行函数,该函数依次返回另一个可观察的对象。

RequestService有一个重载,它接受一个源可观察对象,还有一个requestfactory,它根据源可观察对象的值返回一个IRequest实例。

export interface IRequest<TResponse> {
    __method: string;
    execute(): Observable<TResponse>;
}

class RequestService<TSource, TResponse> {
    public execute(source: Observable<TSource>, requestFactory: (input: TSource) => IRequest<TResponse>): Observable<TResponse> {
        return source.pipe(
            map(x => requestFactory(x)),
            switchMap(x => x.execute()),
        );
    }
}

当然,在服务中做了更多的工作(日志记录、默认错误处理,...),但大多数与问题无关。

现在,这一切都像一个符咒,但我们想做的是,使用switchMap获取请求,默认情况下使用“mergeMap”发布、放置和删除请求。

我们似乎无法让这工作。我们需要在工厂创建IRequest实例后访问它,这只有在我们有可观察的源值的情况下才有可能。但是,在操作员中,我们不能再控制开关地图或合并地图之间的选择。

我们的下一个选择是创建自己的RequestMapOperator,它将创建MergeMapOperatorSwitchMapOperator的实例,并使用适当的next、complete和error方法。但是,rxjs库不会导出SwitchMapOperator

因此,在创建我们自己的订阅类之前,我们想知道我们是否遗漏了什么。

TL;博士

我们想要一个操作符,它根据源可观测值,用mergeMap或switchMap展平到一个新的可观测值。

共有1个答案

满伟彦
2023-03-14

您可以使用RXJS iif函数,该函数将条件函数作为第一个参数,并根据返回的值决定订阅哪个可观察对象。

例如。

class RequestService<TSource, TResponse> {
    public execute(source: Observable<TSource>, requestFactory: (input: TSource) => IRequest<TResponse>): Observable<TResponse> {
        return source.pipe(
            map(x => requestFactory(x)),
            // using mergemap outside because we don't want to cancel inner 
            // observable
            margeMap((x) => 
              iif(() => x.method === "GET", 
               switchMap(x => x.execute()),
               margeMap(x => x.execute())
              )
            )
        );
    }
}

希望有帮助。

 类似资料:
  • 在角度分量的顶部有以下初始化。 在我的组件中的某个地方,我使用选择器对Ngrx存储进行以下调用,以获取可观测数据。所有这些都很好,我得到了我想要的数据。 我需要知道这个可观察的什么时候完成。我需要设置一个布尔值,当所有可观察到的数据都试图完成时,它将关闭加载指示器。这是通过Web服务完成的。 因为可观测的源来自其他地方,所以我无法挂起“完整”回调

  • 有人能向我解释一下为什么运算符可以接受返回或的函数吗? 官方文件说: FlatMap运算符通过将您指定的函数应用于源可观察对象发出的每个项目来转换可观察对象,其中该函数返回本身发出项目的可观察对象。 为什么它也可以返回数组? 例如,它们都是有效的: 但这不起作用:

  • 以下代码未订阅: 但是如果我这样做,它确实订阅: 更新:这个工作太 但当我添加逻辑时,它并没有 我遵循RxJS官方文档:https://rxjs-dev.firebaseapp.com/api/operators/find 我甚至必须在,当我执行时,什么也不会打印出来。我也尝试过使用管道。 对象: 我传递的昵称是将对象与“Devpato”进行比较

  • 我试图将一个角度函数转换为可观察模式,因为它的当前实现与它有一些异步性。为了讨论这个问题,我们举一个简单的例子。 可以通过以下方式将其转换为使用可观察对象: 我所面临的问题(据我所知)是针对无法访问内部选择语句的情况。 如果使用常规主题,订阅函数肯定不会得到任何值,因为事件的顺序是: 函数被调用 主题已创建 值已设置 调用函数订阅,因此仅在此事件发生后获取值 如果使用了BehaviorSubjec

  • 我对Observables和RxJs是新手,我想对回报进行调整。如果第一个选择器返回某个值,我希望第二个选择器可以观察到。但是如果第一个选择器没有返回那个特定的值,我想返回false,而不是(false)。我已经走了这么远,但这返回了一个可观察的结果

  • 我想创建一个作为源变量:。 我想创建一个可观察的,每次值更改时都会生成提要。 我是说,当我这样做的时候: 在我的代码的某个地方,我希望收到订阅的提要,等等。。。 有什么想法吗?