Вы когда-нибудь встречали такие операторы, как materialize и dematerialize в RxJS? А что насчет класса Notification? Вероятно, многие слышали, но не до конца представляли, где их можно применить на практике. В этой статье я расскажу, что делают эти операторы и приведу несколько примеров, которые в будущем вам могут пригодиться. Однажды, интереса ради, я просматривала документацию RxJS и заметила ранее для себя неизвестные операторы: materialize и dematerialize. Первый вопрос, который у меня возник: а где их использовать в реальном проекте? Разберемся вместе? Для начала вспомним, какие типы значений может эмитить объект типа Observable: это next, error и complete. Если вы не помните, что это значит, здесь можно почитать.Соответственно и про observer, набор коллбэков (onNext, onError, onComplete), тоже советую вспомнить. Вот что говорится в документации о materialize операторе: «A function that returns an Observable that emits Notification objects that wrap the original emissions from the source Observable with metadata».Сигнатура оператора: materialize<T>(): OperatorFunction<T, Notification<T> & ObservableNotification<T>>   Получается, materialize оборачивает любое испускаемое observable значение в некий Notification объект и эмитит его как «next». Чем здесь является Notification? Это обертка над observable значением, которая просто добавляет к нему некоторые метаданные: Больше всего нас здесь интересует свойство kind. Именно в нем хранится первоначальный тип значения observable: N — next, E — error, C — complete. Давайте посмотрим на визуализацию работы оператора: Теперь на примере: Давайте разберемся: поток эмитит "one" -> materialize конвертирует в Notification, где kind = "N" (next), а в value записывается передаваемое значение "one". поток завершается -> materialize конвертирует в Notification, где kind = "C" (complete), а в value ничего не записывается, т.к. поток завершился. Из-за того, что materiailze конвертирует значения в Notification объект, observable эмитит их как «next», и мы видим обернутый complete выброс в next обработчике observable.  Еще пример: Опять же из-за того, что materiailze все оборачивает в Notification, даже ошибка попадает в next обработчик. Но что делать, если мы хотим вернуться к исходному выбросу observable? Здесь нам поможет противоположность materialize оператора — dematerialize, с его помощью происходит обратная конвертация. Из документации: «Converts an Observable of Notification objects into the emissions that they represent».Сигнатура оператора:dematerialize<N extends ObservableNotification<any>>(): OperatorFunction<N, ValueFromNotification<N>>   Немного визуализации: Работа оператора в коде: Мы вкратце рассмотрели, что делают операторы materialize и dematerialize. Но где же они могут пригодиться?   Первое, где их можно использовать — во время дебага. Например, вам нужно добавить задержку во время эмита ошибки.   Если это сделать следующим образом:  То в этом случае ошибку вы увидите моментально, задержка не сработает. Это происходит потому, что оператор delay работает только для next выбросов.   Но если использовать изученные нами операторы, то ошибка выводится после заданного времени задержки.  Все из-за того, что ошибка конвертируется в Notification объект с помощью materialize, это позволяет нам применить оператор delay. После (с помощью dematerialize оператора) мы получаем первоначальную ошибку. Исходный код Скажем, нужно объединить 2 observable. Как только один из них завершится, то результирующий observable тоже должен завершиться.  Если реализовать это с помощью оператора merge: Мы не увидим в output "complete". Это случилось из-за того, что merge просто так работает: «The output Observable only completes once all input Observables have completed». И один из способов справиться с этим — использовать операторы materialize и dematerialize: Это то, чего мы добивались. Догадываетесь, почему сработало? Мы знаем, что при использовании merge оператора результирующий поток не завершится при завершении только одного из переданных в него observable. А materialize оператор конвертирует любое значение observable в Notification объект, что воспринимается как «next» выброс. Это позволило нам получить "complete" событие от this.second$ observable в pipe(...).И уже с помощью dematerialize оператора мы получаем исходное значение observable — завершение потока. Исходный код Я постаралась привести несколько примеров использования materialize/dematerialize, чтобы понять, на что они способны и где полезны. Уверена, что эти операторы помогут вам лучше понимать и использовать все возможности RxJS, и вы найдете им интересные способы применения. А вы раньше использовали их? Полезные ссылки https://rxjs.dev/api/operators/materializehttps://rxjs.dev/api/operators/dematerializehttps://rxjs.dev/api/index/class/Notificationhttps://docs.w3cub.com/rxjs/api/index/class/notificationhttps://docs.w3cub.com/rxjs/api/operators/materializehttps://docs.w3cub.com/rxjs/api/operators/dematerializehttps://docs.w3cub.com/rxjs/api/index/function/merge  Frontend developer