eme*_*his 9 javascript design-patterns promise angularjs
我有一个控制器来管理我的数据页面和一个服务,它每隔30秒发出一次HTTP请求,以获取在页面上显示的新数据.我试图用一种可测试的"Angular"方式来编写它,并正确地利用服务.
我可以想到两种基本方法,我猜一个(或两个)都是错的:
控制器将数据存储在$ scope变量中,并执行setInterval
或$timeout
调用服务的方法以获取新数据,然后更新变量.
该服务将数据存储在其自己的变量/属性中,并定期调用其自身以获取新数据.并且控制器以某种方式监视/侦听服务属性以知道何时更新视图.
出于这个问题的目的,考虑一个具体的例子可能会有所帮助.如果HTTP请求失败,我想向视图/用户显示错误.所以假设一个errorMsg
变量需要住在某个地方.它应该存在于控制器中吗?在这种情况下,服务需要每次都返回该值.或者它应该存在于服务中,并且控制器以某种方式监视它.
我尝试过第一种方法,它似乎在控制器中产生了很多逻辑,主要是then()
遵循服务方法的s.我的直觉是#2是正确的方法.但我有点不清楚控制器应该如何收听/观看服务.提前致谢.
让我们从控制器的角度来看这个:
控制器存储数据并查询服务
这叫拉.您正在有效地创建一个服务器响应流,您在控制器中进行轮询
该服务存储数据,控制器观察它
这叫做推.您正在有效地创建结果流并通知消费者更改而不是寻找它们.
这些都是您的问题的有效方法.选择一个你觉得更容易推理的那个.就个人而言,我同意第二个更清洁,因为您不必在控制器中了解它.这应该是一个大概的想法:
function getServerState(onState){
return $http.get("/serverstate").then(function(res){
onState(res.data);// notify the watcher
}).catch(function(e){/*handle errors somehow*/})
.then(function(){
return getServerState(onState); // poll again when done call
});
}
Run Code Online (Sandbox Code Playgroud)
您可以像这样消费:
getServerState(function(state){
$scope.foo = state; //since it's in a digest changes will reflect
});
Run Code Online (Sandbox Code Playgroud)
我们的最后一个问题是它泄漏了范围,因为代码不在控制器上,我们有一个回调注册到一个不再存在的范围.由于我们还没有使用有趣的ES6工具 - 我们必须为getServerState方法返回值提供一个"我已完成"的句柄,例如.done
你将在范围销毁事件上调用的属性.