Понимание RxJS catchError

Я новичок в RxJS и не могу понять, как передаются параметры:

import { catchError, map, Observable, of } from 'rxjs';


let obs$ = of(1,2,3,4,5);
obs$.pipe(
    map(n => {
        if (n === 4) {
            throw 'bloody hell'
        }
        return n;
    }),
    catchError(handleError())
).subscribe(x => console.info(x));

function handleError() {
    return (err: any, caught: Observable<any>): Observable<string> => {
        console.info('error is ', err);
        return of('I', 'II') ;
    }
}

Выход

$ node build/catch-me.js
1
2
3
error is  bloody hell
I
II

Теперь, когда я смотрю на функцию catchError, она говорит:

export function catchError<T, O extends ObservableInput<any>>(
  selector: (err: any, caught: Observable<T>) => O
): OperatorFunction<T, T | ObservedValueOf<O>>;

Мои вопросы:

  1. Как handleError волшебным образом получает значения err и catch из функции catchError? Никуда не передается?
  2. Почему значения err и catch доступны только в функции возврата обработать ошибку?
  3. Передаются ли два типа: один — тип наблюдаемого, второй — ObservableInput?
  4. Как понять, какая операторная функция возвращается из catchError? Наконец, возвращается наблюдаемая величина со значениями I, II.
Принципы SOLID в JavaScript с примерами
Принципы SOLID в JavaScript с примерами
Принцип единой ответственности подразумевает то, что:
Типы привязки данных в Angular
Типы привязки данных в Angular
Привязка данных автоматически поддерживает страницу в актуальном состоянии на основе состояния вашего приложения. Вы используете привязку данных,...
3 паттерна TypeScript, которые я использую в своей повседневной работе
3 паттерна TypeScript, которые я использую в своей повседневной работе
В TypeScript 2.0 в язык был добавлен модификатор readonly.
Мифический Angular - Миф Angular: стили компонентов
Мифический Angular - Миф Angular: стили компонентов
Это очень короткая и интересная для меня тема. В Angular каждый компонент может иметь свои собственные прикрепленные стили. Стили могут находиться в...
Подсказка RxJS [filter, skipWhile]
Подсказка RxJS [filter, skipWhile]
Эта подсказка описывает разницу между операторами filter и skipWhile из библиотеки RxJS .
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
1
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

HandleError — это функция, которая возвращает функцию. Эта функция передается в catchError. Это то же самое, что

catchError((err: any, caught: Observable<any>): Observable<string> => {
  console.info('error is ', err);
  return of('I', 'II') ;
})

Так как это функция handleError возвращает.

Ответ принят как подходящий
Мои вопросы: Как handleError волшебным образом получает значения err и catch из функции catchError? Никуда не передается?

Функция catchError не имеет прямого отношения к «значению ошибки и перехвата». Да, но только статически. Ему просто нужно вернуть функцию правильного типа.

Или, если вы Haskell Curry, вы можете сказать, что handleError принимает свои аргументы отдельно, и вы видите только частичное приложение. Возврат приложения происходит внутри catchError Учтите следующее:

function add(a,b) {
  return a + b;
}
function curry_add(){
  return a => b => a + b;
}

const ten = add(9,1);
const alsoTen = curry_add()(9)(1);

Curry_add волшебным образом не получает никаких параметров. Это то же самое, что и add, но требуется 3 приложения, прежде чем вы сможете получить номер.

Почему значения err и catch доступны только в функции возврата handleError?

Снова частичное приложение, вы можете думать о них как о втором приложении handleError, если хотите. Предоставление вам этих значений является работой оператора catchError, поэтому вы выполняете первое приложение, а оператор выполняет второе за кулисами.

Передаются ли два типа: один — тип наблюдаемого, второй — ObservableInput?

Ошибка и наблюдаемая величина, вызвавшая ошибку.

Как понять, какая операторная функция возвращается из catchError? Наконец, возвращается наблюдаемая величина со значениями I, II.

OperatorFunction преобразует наблюдаемую. Функция pipe знает, как работать только с OperatorFunction, поэтому каждый оператор в конечном итоге создает OperatorFunction. Таким образом, map, tap, switchMap, catchError и т. д. должны создать для вас OperatorFunction. Вы можете просто создать его самостоятельно, если хотите.

Например:

function filterFours(a: Observable<number>): Observable<number> {
  return new Observable(observer => {

    const sub = a.subscribe({
      next: v => {
        if (v != 4) observer.next(v);
      },
      complete: () => observer.complete(),
      error: e => observer.error(e)
    });

    return {
      unsubscribe: () => sub.unsubscribe()
    };

  })
}

of(1,4,2,4,3,4,5,4).pipe(
  filterFours
).subscribe(console.info);

Это семантически то же самое:

of(1,4,2,4,3,4,5,4).pipe(
  filter(v => v != 4)
).subscribe(console.info);

То, что возвращает filter(v => v != 4), — это то же самое, что и filterFours. Они делают то же самое.

Отличный пример с карри. Спасибо за подробные разъяснения

lopah elision 14.02.2023 09:24

Другие вопросы по теме