Javascript Angular.js-在工厂/服务中设置超时以延迟事件侦听器
当客户端第一次启动时,我试图延迟广播的第一次迭代,直到控制器中的Javascript Angular.js-在工厂/服务中设置超时以延迟事件侦听器,javascript,angularjs,Javascript,Angularjs,当客户端第一次启动时,我试图延迟广播的第一次迭代,直到控制器中的$watchCollection准备好捕捉它。但是,setTimeout()并不能解决这个问题,也不能使它成为一个完全没有eventlistener的地方。使用$timeout尝试此操作,结果相同。为什么会这样 angular.module('monitorApp') .factory('sseHandler', function ($rootScope) { var source = new EventSource('/s
$watchCollection
准备好捕捉它。但是,setTimeout()
并不能解决这个问题,也不能使它成为一个完全没有eventlistener的地方。使用$timeout
尝试此操作,结果相同。为什么会这样
angular.module('monitorApp')
.factory('sseHandler', function ($rootScope) {
var source = new EventSource('/subscribe');
var sseHandler = {};
setTimeout(function() {
source.addEventListener('message', function(e) {
$rootScope.$apply(function (){
result = JSON.parse(e.data);
event = Object.keys(result)[0];
switch(event) {
case "cpuResult":
sseHandler.result = result;
console.log(sseHandler.result.cpuResult.timestamp);
break;
}
});
});
return sseHandler;
}, 1000);
});
编辑:
我把它放在我的节点服务器上,当客户端连接时,SSE广播会立即发送给它。服务source.addEventListener
成功捕获第一次广播。但此时控制器尚未就绪,$scope.$watchCollection
将错过第一次广播
angular.module('monitorApp')
.controller('cpuCtrl', ['$scope', 'sseHandler', function($scope, sseHandler) {
var cpuUpdate = function (result) {
$scope.available = result.cpuResult.avaiable;
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['15m'].data
$scope.last5 = result.cpuResult.metrics['5m'].data
$scope.lastMinute = result.cpuResult.metrics['1m'].data
}
$scope.$watchCollection(function(){
return sseHandler.result;
}, function(){
if (sseHandler.result.cpuResult) {
console.log("yes");
cpuUpdate(sseHandler.result);
}
});
}]);
这边怎么样?工厂将正常返回对象。$timeout之后,将设置侦听器,并且返回的对象通常应填充数据
angular.module('monitorApp')
.factory('sseHandler', function ($rootScope, $timeout) {
var source = new EventSource('/subscribe');
var sseHandler = {};
$timeout(function() {
source.addEventListener('message', function(e) {
$rootScope.$apply(function (){
result = JSON.parse(e.data);
event = Object.keys(result)[0];
switch(event) {
case "cpuResult":
sseHandler.result = result;
console.log(sseHandler.result.cpuResult.timestamp);
break;
}
});
});
}, 1000);
return sseHandler;
});
如果您希望(出于任何原因)在sseHandler
连接到服务器时实例化控制器并准备好执行操作,最可靠的方法是在sseHandler
上使用init()
或connect()
方法,并让控制器在准备好时调用它
例如:
你不能耽误这样的服务。超时回调的返回值被忽略。你应该改用承诺……我如何将“一旦控制器完成/实现”包装成承诺?不清楚你想要实现什么。为什么要延迟设置服务的属性,因为控制器可以随时访问它。最可能的意思是,您希望延迟控制器访问属性,直到属性被设置,但这不是必需的(特别是如果您使用
$watch
)。请澄清您试图实现的目标,这样我们就不会追踪鬼魂:)请查看原始消息中的编辑。您不能发出“watchcollection ready”之类的事件,然后在该事件发生时广播吗?显然只有一次。
.factory('sseHandler', function ($rootScope) {
var sseHandler = {};
sseHandler.init = function () {
var source = new EventSource('/subscribe');
source.addEventListener('message', function (evt) {
$rootScope.$apply(function () {
result = JSON.parse(evt.data);
event = Object.keys(result)[0];
switch (event) {
case "cpuResult":
sseHandler.result = result;
console.log(sseHandler.result.cpuResult.timestamp);
break;
}
});
});
};
return sseHandler;
})
.controller('cpuCtrl', function ($scope, sseHandler) {
function cpuUpdate(result) {
$scope.available = result.cpuResult.avaiable;
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['15m'].data
$scope.last5 = result.cpuResult.metrics['5m'].data
$scope.lastMinute = result.cpuResult.metrics['1m'].data
}
$scope.$watchCollection(function () {
return sseHandler.result;
}, function () {
if (sseHandler.result && sseHandler.result.cpuResult) {
console.log("Yes !");
cpuUpdate(sseHandler.result);
}
});
// Now that everything is set up, let's initialize `sseHandler`
sseHandler.init();
});