Rxjs: в зависимости от наблюдаемого значения, канал с mergeMap или switchMap - PullRequest
1 голос
/ 14 марта 2019

У нас есть служба запросов, которая выполняет http-запросы.Все запросы реализуют интерфейс IRequest, который содержит http-метод и функцию execute, которая, в свою очередь, возвращает другую наблюдаемую.

RequestService имеет перегрузку, которая принимает наблюдаемую исходную информацию, и фабрику запроса, которая возвращает экземпляр 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 для GET-запросов и 'mergeMap' для запросов POST, PUT, DELETE по умолчанию.

Мы не можемпохоже, это работает.Нам нужен доступ к экземпляру IRequest после того, как он был создан фабрикой, что возможно, только если у нас есть значение исходной наблюдаемой.Однако, находясь в операторе, мы больше не можем контролировать выбор между switchMap или mergeMap.

Нашим следующим выбором было создание собственного RequestMapOperator, который бы создавал экземпляр MergeMapOperator или SwitchMapOperatorи используйте соответствующие методы next, complete и error.Однако SwitchMapOperator не экспортируется библиотекой rxjs.

Поэтому перед созданием нашего собственного класса Subscriber, который будет представлять собой просто комбинацию MergeMapSubscriber и SwitchMapSubscriber, мы хотели бы знать,мы что-то упускаем.


TL; DR

Нам нужен оператор, который, в зависимости от значения наблюдаемой источника, сглаживается до новой наблюдаемой сmergeMap или switchMap.

1 Ответ

0 голосов
/ 14 марта 2019

Вы можете использовать функцию RIFJS 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())
              )
            )
        );
    }
}

Надеюсь, что это поможет.

...