Недавно я услышал вопрос, стоит ли углубляться в планировщики RxJS. В этой статье я поделюсь своим мнением по этой теме.

RxJS путешествие

Я регулярно использую библиотеку RxJS более года. Должен признать, что мне очень нравится реактивное программирование, и мне определенно нравится эта библиотека. Я до сих пор помню первый день этого путешествия, и, несомненно, это не было ложе из роз. Меня поразило огромное количество операторов и прочего. Сначала я познакомился с группой операторов, у которых есть аналоги в простом JavaScript, такие как map, filter, reduce. Затем я сосредоточился на наблюдаемых более высокого порядка, различных типах Subject и проблеме многоадресной рассылки. Обладая знаниями RxJS, у меня не было проблем с работой с приложениями Angular с использованием библиотек ngrx. Однажды я натолкнулся на понятие планировщика. Я думаю, что следующий доклад - отличный источник глубоких знаний по этой теме.

Однако возникает вопрос, действительно ли разработчику нужно заботиться о планировщиках RxJS. С одной стороны, вы можете написать довольно мощный реактивный код, не зная о существовании планировщиков. С другой стороны, всегда желательно иметь хотя бы базовые знания и понимание темы.

В этой статье я приведу три примера, в которых удобно использовать планировщики RxJS.

Выражение проверено после проверки

Я думаю, что каждый разработчик Angular видел эту ошибку и должен был найти способ решить эту проблему.

Давайте вызовем ошибку

Выполнение приведенного выше кода приводит к ошибке ExpressionChangedAfterItHasBeenCheckedError.

Первый способ исправить ошибку - обновить свойство name с помощью setTimeout

Более профессиональный подход - еще раз запустить обнаружение изменений.

Наконец, вы можете использовать планировщики RxJS, чтобы исправить ошибку

Если вы используете asyncScheduler, обратный вызов, предоставленный методу schedule, будет выполняться асинхронно, как setTimeout со значением по умолчанию ценить. В результате будет запланирована новая макро-задача.

Мокинг удаленного сервиса

Если вы пишете модульный тест для интеллектуального компонента, обращающегося к службе, вы, вероятно, предоставляете имитацию службы, которая возвращает примерные данные. Angular использует службу HttpClient для выполнения внутренних запросов. Типичный сервис может выглядеть так

а отрывок из тестового файла будет содержать следующий код

Тесты могут пройти, но, согласно Netanel Basal, это обман, поскольку вы возвращаете синхронный of observable вместо асинхронного потока, который будет реальным сценарием.

Если вы думаете, что это не имеет большого значения, смотрите статью.

Вы можете быстро решить проблему, указав необязательный второй аргумент функции of, а именно планировщик. Поскольку вы хотите генерировать значение асинхронно, asyncScheduler - идеальный выбор.

В приведенной выше реализации mockCars будет генерироваться асинхронно, и тест будет иметь гораздо более реальную реализацию CarService.

Тестирование наблюдаемой на основе времени

И последнее, но не менее важное: планировщики RxJS очень полезны, когда вы хотите протестировать кусок кода RxJS, который использует операторы, работающие со временем, такие как interval или delay. Я считаю, что использование жасминовых шариков - безусловно, лучший способ протестировать код RxJS.

Представьте, что вы хотите протестировать следующий эффект ngrx

Из-за оператора deboundTime было бы невозможно протестировать эффект в этой форме с помощью жасминовых шариков. Вам нужно будет протестировать это традиционным способом, подписавшись на поток и либо вручную вызвать done обратный вызов, либо использовать утилиту fakeAsync.

Однако эффект также можно определить как функцию. В результате вы можете переписать вышеупомянутый эффект в эту форму

Теперь приложение будет полагаться на значения по умолчанию, если вы не предоставите объект конфигурации. В производственном режиме разницы не будет, однако при таком подходе вы можете проверить эффект с помощью жасминовых шариков, предоставив планировщик тестов.

Планировщик свяжет предоставленное значение debounce с виртуальным временным отрезком, так что 30 будет означать 3 кадра.

При таком подходе вы можете одним выстрелом убить двух зайцев, а именно эффект работает как и раньше, и вы можете проверить его с помощью жасминовых шариков.

Выводы

Планировщики RxJS - это еще одна веха на пути к тому, чтобы стать мастером библиотеки. Я считаю, что в какой-то момент вам стоит познакомиться с темой хотя бы на базовом уровне.

Знание о существовании планировщиков может помочь вам, особенно во время тестирования. Кроме того, это хорошая альтернатива подробному setTimeout, если вам нужно выполнить задачу асинхронно. Также доступен asapScheduler, который устанавливает другую микрозадачу.

Надеюсь, вам понравилась статья и вы узнали что-то новое о библиотеке RxJS. Если да, пожалуйста, поаплодируйте мне 👏.