Подтвердить что ты не робот

Должна ли служба Angular иметь статус?

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

Причины для состояния обслуживания:

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

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

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

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

4b9b3361

Ответ 1

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

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

Посмотрите на службу $http: вы можете получить экземпляр этой службы, вызывающий

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

А затем вызовите

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

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

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

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

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

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

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