Я играю с Rxjs, наблюдаемыми объектами и картами и обнаружил странное поведение Observable.throw(error)
, которое не могу объяснить.
Если у меня есть поток Rx, который использует оператор карты, и я хочу прервать процесс, я бы ожидал, что метод Observable.throw
будет подходящим, однако, похоже, это не так.
Рассмотрим следующий пример:
Rx.Observable.just("test 1").subscribe(
x => console.log(x),
err => console.log(err),
() => console.log("done, no errors")
);
Теперь давайте представим ошибку, если я использую обычный throw
из Javascript, он работает как положено:
Rx.Observable.just("test 2").map(
x => { throw new Error(x) }
).subscribe(
x => console.log(x),
err => console.log(err),
() => console.log("done - error was thrown, as expected")
);
Вывод:
Ошибка: тест 2 в Rx.Observable.just.map.x ((index):58) в c (rx.all.compat.js:61) в e.onNext (rx.all.compat.js:5169) ( ...)
Но если я использую Rx.Observable.throw(...), обратный вызов error
от следующего подписчика никогда не вызывается, а вместо этого будет вызываться обратный вызов next
с каким-то странным объектом, который кажется объектом ошибки Rx.
Rx.Observable.just("test 3").map(
x => Rx.Observable.throw(x)
).subscribe(
x => console.log(x),
err => console.log(err),
() => console.log("done - it does not work... why?")
);
Вывод:
b_subscribe: f(a)ошибка: "тест 3" планировщик: a__proto__: g
Как указал @Whymarrh, кажется, что он работает нормально, если вместо этого я использую оператор flatMap.
Оператор Map применяет выбранную вами функцию к каждому элементу, испускаемому исходным Observable, и возвращает Observable, который испускает результаты применения этих функций.
Документация для Observable.throw:
Возвращает наблюдаемую последовательность, которая завершается исключением, используя указанный планировщик для отправки одного сообщения onError.
Кто-нибудь знает, почему при использовании Observable.throw внутри оператора карты не вызывается обратный вызов error
и почему процесс не прерывается?
Я знаю, что могу просто использовать обычный бросок и двигаться дальше, у меня уже есть рабочее решение, я публикую этот вопрос из любопытства, чтобы лучше понять, как работает фреймворк.
Небольшое напоминание: в stackoverflow действует политика вежливости.
flatMap
работает (и это было бы ожидаемым решением): jsbin.com/bododomeku /edit?js,console (здесь я использую JS Bin, чтобы иметь удобный вывод на консоль.) - person Whymarrh   schedule 08.02.2017map
, будет куча дубликатов, которые предлагаютflatMap
в качестве решения. - person Whymarrh   schedule 08.02.2017flatMap
— это оператор, который вам нужен, если вы хотите вернуть Observable (Rx.Observable.throw(error)
) вместо значения (throw new Error()
). Использованиеmap
приведет к вызовуonNext
с потоком, в котором есть ошибка. - person Whymarrh   schedule 08.02.2017throw
генерирует исключение, которое просто всплывает вверху процесса.Observable.throw
просто создает структуру, представляющую ошибку. Дляmap
это значение, как и любое другое, для вызова обработчика успеха. ЧтобыflatMap
, он имел структуру и был развернут, чтобы вызвать обработчик ошибок. - person Bergi   schedule 08.02.2017