Angular服务应该有州吗?

时间:2013-01-09 16:35:11

标签: service angularjs state

最近,我和一些同事正在讨论AngularJS服务是否应该有州。我们提出了一些支持和反对的论据,我希望得到关于这个主题的更多想法和反馈。在我的搜索中,我发现this,但似乎没有提到任何明确的最佳做法。在无客户端的世界中,服务永远不应该保持状态,但我开始认为它可能是客户端可接受的,因为它是一个不同的问题。

服务持有状态的原因:

  1. 多个线程不会访问该服务。每个浏览器都有自己的服务实例。
  2. 允许服务仅保留其关心的状态,而不是将其存储在rootScope中。封装
  3. 服务未成立状态的原因:

    1. 服务不再是幂等的。调用函数可能会更改状态,因此在根据服务状态调用它时可能会有不同的结果。
    2. 我认为总的来说这会更容易测试。
    3. 可能在“for services holding state”部分中解决#2的一种方法是在rootScope上设置包含应用程序当前状态的appState对象。然后将所有州聚集在一个位置,然后您只需在服务中提取所需的内容。我找到了这个并且想知道

4 个答案:

答案 0 :(得分:13)

这可能取决于你所说的“州”,但在很多情况下我认为答案是肯定的:服务应该保持状态。

例如,如果您有一项负责与API通信的服务,则该服务可以保持身份验证状态。

顺便说一句,我不确定对于AngularJS服务有多少幂等性 - 它们是单身人士,因此本身就有某种状态。您可以(并且在某些情况下必须)在服务上创建幂等方法,但这是一个单独的问题。

答案 1 :(得分:9)

在AngularJS中,服务are passed in via factory function。基本上它们是可以包含某些状态的对象(例如,用于缓存或存储执行其操作所需的数据)。

可以同时具有/不具有状态的一个好的解决方案是返回包含状态的对象的服务(可能实际上是函数)。

查看$http服务:您可以获取此服务的实例调用

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

然后通过

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

ngResource相同:使用服务可以获得具有某些可以执行所需操作的状态的对象。

所以基本上我认为这是最好的选择:从一个方面你可以通过将可以被动作修改的状态移动到单独的对象中来避免“副作用”,而不是存储在服务本身中,但是可以在该对象中具有特定状态能够存储自定义信息(如身份验证信息等)。

答案 2 :(得分:1)

IMO是的,服务可以有州。我说“可以”作为一种服务可以被认为是类似于经典无客户服务的东西 - 提供者,但它也可能意味着完全不同的东西,在angularJS中。作为应用程序中的rootScope-y单实例元素,它可以仅用于管理状态。在我的例子中,这使我能够确保许多应用程序的状态结构是相同的,即使在引导期间为每个应用程序定义了各自的状态结构,当更改该模块时,诸如会话状态之类的内容总是相同并更新。 / p>

答案 3 :(得分:-4)

服务不应具有状态的原因是,当您有多个线程访问服务时,它会导致竞争条件。

服务中状态的常见问题是:

  1. 线程1写入状态
  2. 线程2写入状态
  3. 线程1从状态读取
  4. 线程2从状态读取
  5. 线程1现在有错误的值。

    话虽这么说,javascript目前是单线程的,所以你不会有像这样的线程访问问题。但是,如果我有一个多个异步$ http调用都写入同一服务变量的服务,我会担心。如果只是这样我晚上可以睡得更好,我会尝试编写所有服务方法,以便对实际数据进行传递。

    相反,为了维护服务中的状态,您可以考虑尽可能地将状态放在后端。像#34;认证"或者甚至可以保持和查询宽度和高度。这可以打开一些可能性,允许用户离开应用程序,返回并查找仍然设置和登录的所有首选项。您可以在cookie中存储会话ID并将所有这些内容保存在后端。

    如果您确实采用了单独的对象来存储状态的路径,那么当状态中的某些内容发生更改时,您可以从服务中向它发出$ how to emit events from a factory。这将具有使多个服务能够修改统一应用程序状态的良好副作用,因为状态不存储在任何一个服务中(或者更糟糕地分散在多个服务中)。