Впервые я наткнулся на функцию defer около года назад, когда занялся почти готовым приложением Angular. На самом деле оказалось, что в этом нет необходимости. С тех пор я не видел никакого разумного применения этой функции до тех пор, пока Кшиштоф Тшесневски не выступил с докладом на местном собрании Angular. Потом я просветлел и нашел по крайней мере одно достойное упоминания применение функции defer.
Короткое напоминание JS
Прежде чем мы перейдем к функции defer, давайте кратко рассмотрим правила области видимости JavaScript.
Приведенный ниже код не будет работать, так как в вашей среде IDE вы увидите красное подчеркивание:
переменная с областью видимости блока "bar" используется перед ее объявлением
Однако следующий код прекрасен:
Следовательно, вы можете ссылаться на переменную bar в выражении, если выражение выполняется после инициализации переменной.
Образец наблюдателя
Допустим, вы хотите иметь службу уведомлений, которая просто следует шаблону Observer, а именно: вы можете отправить новое уведомление, и все подписанные объекты получат сообщение. Кусок пирога с использованием RxJS.
Хотя он очень похож на пример из официальных документов Angular, есть одна вещь, на которую я всегда жалуюсь, а именно на неправильный порядок полей классов. В общем, за общедоступными полями должны следовать защищенные и частные. Это урок, который я извлек из мира Java.
Итак, давайте попробуем переместить общедоступное поле notifications $ перед частными полями.
К сожалению, появляется следующее сообщение об ошибке:
свойство используется до его инициализации
Как это исправить?
Придите на помощь
Надеюсь, вы заметили, что проблема, с которой мы столкнулись, очень похожа на проблему из абзаца Краткое напоминание JS.
Согласно официальной документации RxJS, функция defer:
Создает Observable, который при подписке вызывает фабрику Observable, чтобы создать Observable для каждого нового Observer.
И это именно то, что нам нужно! Нам нужно отложить создание наблюдаемого объекта notifications $, чтобы notificationsSubject уже был инициализирован.
Давайте посмотрим на реализацию сервиса:
При использовании вышеупомянутого решения служба работает так, как ожидалось, и соблюдается руководство по стилю, а именно, в первую очередь общедоступные поля.