gpt4 book ai didi

javascript - AngularJS websockets 太快了

转载 作者:行者123 更新时间:2023-11-30 10:14:49 25 4
gpt4 key购买 nike

我正在使用 AngularJS 来支持我的网络应用程序。最近我决定在与 RabbitMQ 的混合中引入 Stomp over websockets。我一直遇到的一个问题是,有时从后端发送的消息频率太高,以至于 Angular 无法触发一些事件,在这个过程中丢失数据。

应用程序相当复杂,因此有时一条消息可能会通过以下链

  1. StompJS Angular 服务包装器。使用 $rootScope.$broadcast 在新消息到达时通知组件
  2. 注册到在 $rootScope 上广播的消息的 Controller 。然后, Controller 更新绑定(bind)或向组件发送另一个事件以执行一些数据更新。

正如我提到的,有时 范围不会正确更新,即使正在发送事件并且正在填充值, View 也不会显示更新后的值。我已经使用了 $scope.$apply, $timeout, $scope.$digest 并且似乎没有任何效果......例如,如果我有 2 个数据包一个接一个地到来并且它们之间在套接字上几乎没有延迟没有任何反应但是如果有一段相同的代码功能正常。如何克服这个问题?

根据网友的一些问题进一步举例说明:

我将举一个最简单的例子:我从后端运行的作业中获取进度报告。基本上它告诉我在 Cassandra 数据库中写入了多少行。所以我收到了类似 {wrote: 8000, total: 4000000} 的通知。随着工作人员在数据库中写入,“写入”正在增加,并且由于有多个工作人员,有时这些通知会被推送得非常快。我编写了一个自定义网格组件,用于监听诸如 grid:updateCell 之类的事件(它允许我使用进度报告更新单元格)。每次数据包到达套接字时,我都会广播该事件($scope.$broadcast,因为网格是 Controller 页面的子项)。我注意到尽管事件被捕获并且网格事件也被成功更新数据模型而不是 UI 触发,但并非所有来自套接字的更新都反射(reflect)在 UI 中

最佳答案

在我看来,您可能在这里发生了一些事情。

1) 使用 $scope.$broadcast 会降低作用域,如果您有很多嵌套作用域,这可能会很重。我更喜欢将事件监听器附加到 $rootScope 并使用 $emit ,它只广播到当前范围并且更快。我为此提供以下服务

    /**
* @ngdoc service
* @name someModule.eventbus
* @requires $rootScope
*
* @description
* Provides a eventing mechanism when a user cna broadcast and subscribe to application wide events.
*/
angular.module('someModule').factory('eventbus', [
'$rootScope',
function ($rootScope) {
/**
* @ngdoc function
* @name subscribe
* @methodOf someModule.eventbus
*
* @description
* Subscribes a callback to the given application wide event
*
* @param {String} eventName The name of the event to subscribe to.
* @param {Function} callback A callback which is fire when the event is raised.
* @return {Function} A function tht can be called to unsubscrive to the event.
*/
var subscribe = function (eventName, callback) {
return $rootScope.$on(eventName, callback);
},

/**
* @ngdoc function
* @name broadcast
* @methodOf someModule.eventbus
*
* @description
* Broadcasts the given event and data.
*
* @param {String} eventName The name of the event to broadcast.
* @param {object} data A data object that will be passed along with the event.
*/
broadcast = function (eventName, data) {
$rootScope.$emit(eventName, data);
};

return {
subscribe: subscribe,
broadcast: broadcast
};
}
]);
  1. 您可能不会在 Angular 摘要周期内触发更新,这可以解释为什么您只获得一些更新。尝试使用摘要循环进行更新(将函数放在 $timeout block 中,这是 $scope.$apply 的推荐方法

    $超时(函数(){ 做更新(dataFromMessageBus);});

  2. 如果您收到大量消息,您应该使用去抖功能,请参阅 lodash-debouce .一个人只能真正处理大约 200 毫秒的数据 block ,因此通常每 200 毫秒更新一次将是一个人可以接受的最多的时间。我个人会每秒左右执行一次,比如交易应用程序等。

(使用 lodash - 去抖动)

function (messageBus) {
var debounceFn = _.debounce(function () {
$timeout(function() {
doUpdate(data);
});
}, 1000);

// just assuming here about your socket / message bus stuff
messageBus.onMessageRecieved(function () {
//Call debounce function which will only actually call the inner func every 1000ms
debounceFn();
});

}

关于javascript - AngularJS websockets 太快了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24462412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com