Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Service 角度服务是否应该具有状态?_Service_Angularjs_State - Fatal编程技术网

Service 角度服务是否应该具有状态?

Service 角度服务是否应该具有状态?,service,angularjs,state,Service,Angularjs,State,最近,我和一些同事讨论了AngularJS服务是否应该有状态。我们提出了一些支持和反对的论据,我想得到更多关于这个问题的想法和反馈。在我的搜索中,我发现了一些问题,但似乎没有提到任何明确的最佳实践。在非客户端世界中,服务不应该保持状态,但我开始认为它可能是可以接受的客户端,因为这是一个不同的问题 服务持有状态的原因: 该服务不会被多个线程访问。每个浏览器都有自己的服务实例 允许服务仅保留其关心的状态,而不是将其存储在根范围中。封装 服务不保持状态的原因: 服务不再是幂等的。调用函数可能会改变状态

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

服务持有状态的原因:

  • 该服务不会被多个线程访问。每个浏览器都有自己的服务实例
  • 允许服务仅保留其关心的状态,而不是将其存储在根范围中。封装
  • 服务不保持状态的原因:

  • 服务不再是幂等的。调用函数可能会改变状态,因此在基于服务状态调用函数时可能会产生不同的结果
  • 我认为总的来说,这将更容易测试

  • 在“for services holding state”部分中处理#2的一种方法是在包含应用程序当前状态的rootScope上设置appState对象。然后所有的州都会集中在一个地方,然后你只需要在你的服务中从中提取你需要的东西。我发现了这一点,想知道这可能取决于你所说的“状态”,但在许多情况下,我认为答案是肯定的:服务应该保持状态

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


    顺便说一句,我不确定幂等性对AngularJS服务有多重要——它们是单例的,因此本质上有一些状态。您可以(在某些情况下必须)在服务上创建幂等方法,但这是一个单独的问题。

    是的,服务可以有状态。我说“can”作为一种服务可以被认为是一种类似于经典的非客户端服务的东西——提供者,但在angularJS中,它也可以意味着完全不同的东西。例如,作为应用程序中的rootScope-y one-instance元素,它可以单独用于管理状态。在我的例子中,这使我能够确保许多应用程序的状态结构是相同的,即使它们各自的状态结构在引导过程中为每个应用程序定义,会话状态之类的东西在模块更改时总是相同并更新的。

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

    一个很好的解决方案可以同时考虑有/没有状态的缺点,就是当服务(实际上可能是函数)返回包含状态的对象时

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

    var x = $http({url:'...'});
    
    然后打电话过来

    var result = x.get() //actually `$http.get` is shortcut of this operation
    
    ngResource
    相同:使用服务,您可以获得具有某些状态的对象,这些状态可以执行所需的操作


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

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

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

  • 线程1写入状态
  • 线程2写入状态
  • 线程1从状态中读取数据
  • 线程2从状态读取数据
  • 线程1现在具有错误的值

    这就是说,javascript目前是单线程的,所以不会出现这样的线程访问问题。但是,如果我有一个服务,其中多个异步$http调用都写入同一个服务变量,我会担心。如果我晚上能睡得更好的话,我会尝试写下我所有的服务方法,让它们成为实际数据的传递

    相反,在维护国家的服务时,你可以考虑尽可能多地把国家置于后端。可以维护和查询诸如“已验证”甚至宽度和高度之类的内容。这可以打开一些可能性,允许用户离开应用程序,返回并发现他们所有的首选项仍在设置和登录。您可以在cookie中存储会话id,并将所有这些内容保存在后端


    如果您确实使用了一个单独的对象来存储状态,那么当状态发生更改时,您可能能够从服务向其发送$emit:。这将产生一个很好的副作用,即让多个服务能够修改统一的应用程序状态,因为状态没有存储在任何一个服务中(或者更糟的是分布在多个服务中)。

    保持身份验证状态的好处。至于使服务幂等,我的意思是,就像你提到的,具有幂等方法。谢谢你的回答。把它保持在状态的好处是你可以使用一个引用变量。因此,您可以创建复杂数据结构的清晰描述!关于$http和$resource的优点。另外,我喜欢你只存储不会被服务调用的函数修改的状态(初始化服务时除外)。你自己说过,javascript是单线程的,因此没有竞争条件,甚至不能通过webworkers,因为webworkers可以共享对对象的引用。您指的是后端,但表示层的状态与持久性无关。