Должен ли Угловой сервис иметь состояние?

Недавно у некоторых коллег и я обсуждали, нужно ли иметь услуги AngularJS или нет. Мы придумали некоторые аргументы за и против, и я хотел получить дополнительные мысли и отзывы по этому вопросу. В моем поиске я нашел это , но, похоже, практика упомянутый. В мире клиентской стороны служба никогда не должна оставаться в состоянии, но я начинаю думать, что она может быть приемлемой на стороне клиента, потому что у нее другая проблема.

Причины для предоставления услуг:

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

Причины, по которым службы не сохраняются:

  1. Сервисы больше не являются идемпотентными. Функции вызова могут изменять состояние и, следовательно, могут иметь разные результаты при вызове на основе состояния службы.
  2. Я бы подумал, что в целом это было бы легче протестировать.

Один из способов, который мог бы адресовать номер 2 в разделе «Состояние обслуживания», - это иметь объект appState, установленный на rootScope, который содержит текущее состояние приложения. Тогда все государство будет собрано в одном месте, а затем вы просто вытащите то, что вам нужно, в вашем сервисе. Я нашел это и задался вопросом

18
nl ja de

4 ответы

Вероятно, это зависит от того, что вы подразумеваете под «состоянием», но во многих случаях я думаю, что ответ будет да: службы должны сохранить состояние.

Например, если у вас есть служба, отвечающая за связь с API, эта служба может содержать состояние аутентификации.

Кстати, я не уверен, сколько идемпотенций имеет значение для сервисов AngularJS - они однотонные и, следовательно, имеют определенное состояние. Вы могли (и в некоторых случаях должны) создавать идемпотентные методы в службе, но это отдельная проблема.

13
добавлено
Большая вещь о том, чтобы удерживать его в состоянии, означает, что вы можете использовать контрольную переменную. И из-за этого вы можете создать четкое описание сложной структуры данных!
добавлено автор Exitos, источник
Хороший вопрос о состоянии аутентификации. Что касается предоставления сервиса идемпотент, я имел в виду, как вы уже упоминали, идемпотентные методы. Спасибо за Ваш ответ.
добавлено автор testing123, источник

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

Одним из хороших решений, которые могут иметь оба недостатка в наличии/отсутствии состояния, является то, что служба (которая может быть фактически функционирует) возвращает объект, который содержит состояние.

Взгляните на сервис $ http : вы можете получить экземпляр этого вызова службы

var x = $http({url:'...'});

И затем позвоните

var result = x.get() //actually `$http.get` is shortcut of this operation

То же самое с ngResource : используя службу, вы получаете объект с некоторым состоянием, которое может выполнять требуемые действия.

Поэтому я считаю, что это лучший вариант: с одной точки вы избегаете «побочных эффектов» путем перемещения состояния, которое может быть изменено действием на отдельный объект, а не храниться в самом сервисе, но может иметь определенное состояние в этом объекте, чтобы иметь возможность хранить пользовательскую информацию (например, информацию auth и т. д.).

9
добавлено
Хорошие моменты о $ http и $ resource. Кроме того, мне нравится ваша мысль о сохранении состояния, которое не будет изменено функциями, вызываемыми службой (за исключением, может быть, при инициализации службы).
добавлено автор testing123, источник

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

Общей проблемой с состоянием службы является:

  1. поток 1 записывает в состояние
  2. поток 2 записывает в состояние
  3. поток 1 читается из состояния
  4. поток 2 читается из состояния

Поток 1 теперь имеет неправильное значение.

Это, как говорится, JavaScript в настоящее время однопоточный, поэтому у вас не будет проблем с доступом к потоку, подобных этому. Тем не менее, я был бы обеспокоен, если бы у меня была служба, в которой все асинхронные $ http-вызовы записывались в одну и ту же служебную переменную. Если бы только я мог лучше спать ночью, я бы попытался написать все свои методы обслуживания, чтобы они были сквозными данными для фактических данных.

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

Если вы выбрали путь к отдельному объекту для хранения состояния, вы могли бы исправить его из службы, если что-то в состоянии изменилось: как испускать события с завода . Это могло бы иметь хороший побочный эффект, заключающийся в том, что несколько служб могут изменять состояние унифицированного приложения, поскольку состояние не сохраняется в какой-либо одной службе (или, что еще хуже, распределяется между несколькими службами).

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

ИМО да, услуги МОГУТ иметь состояния. Я говорю, что «может», поскольку услугу можно рассматривать как нечто похожее на классическую не клиентскую службу - провайдера, но это также может означать нечто совершенно иное, в angularJS. Как элемент rootScope-y one-instance в приложении, он может использоваться исключительно для управления состоянием, например. В моем случае это позволяет мне обеспечить, чтобы структура штата была одинаковой во многих приложениях, и хотя их индивидуальная структура состояния определена для каждого в процессе начальной загрузки, такие вещи, как состояние сеанса, всегда одинаковы и обновляются, когда этот модуль изменяется.

1
добавлено
Angular — русскоговорящее сообщество
Angular — русскоговорящее сообщество
3 960 участник(ов)

Общаемся на темы Angular 4+, его экосистемы, TypeScript, NativeScript и т.д. По вопросам SSR, Angular Universal @angular_universal_ru См. также: @typescript_ru, @react_js, @nodejs_ru, @js_ru Вакансии и поиск работы: @javascript_jobs

Angular.js (1.x) — русскоговорящее сообщество
Angular.js (1.x) — русскоговорящее сообщество
704 участник(ов)

Общаемся и обсуждаем темы, посвященные Angular 1.x и экосистеме.

AngularJS, Javascript
AngularJS, Javascript
370 участник(ов)

Angularjs russian chat