- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将尝试解释我的实际设置,其背后的想法,出现的问题以及围绕它的尝试。
上下文
我有一个PHP5.3后端向Javascript(使用jQuery 1.7.x)提供“事件”(事件是一个包含一些数据的标准数组,其中包括唯一的序列号)。使用jsonp(在子域上)并在服务器端进行长轮询来检索事件。第一个事件的ID为1,然后随着每个新事件的增加而递增。客户端跟踪“上次检索到的事件ID”,该值从0开始。对于每个长轮询请求,它都提供该ID,因此后端仅返回在该事件之后发生的事件。
按照以下方式处理事件:接收到事件(通过jsonp回调)后,将它们存储在eventQueue变量中,并将“最后检索到的事件ID”更新为接收到并存储在队列中的最后一个事件。然后调用一个函数来处理下一个排队的事件。该函数检查事件是否已经被处理(通过在事件开始处理时设置的另一个变量的方式),如果不执行任何操作,则调用堆栈将我们带回到jsonp回调,其中新发出长轮询请求。 (这将在处理其他事件时重复排队新事件的过程。)但是,如果当前没有正在处理的事件,它将验证队列中是否还有事件,如果是,它将处理第一个事件(具有最低ID)。 “处理事件”可以是与我的应用程序相关的各种任务,但与我所遇到的问题或上下文无关。例如,更新变量,页面上的消息等。将某个事件视为“正在处理”(某些事件会进行ajax调用以获取或发送数据,在这种情况下,此操作会在其成功的ajax回调中发生),调用另一个名为eventComplete的函数。该函数从事件队列中删除已处理的事件,确保将用于处理是否正在处理事件的变量设置为false,然后调用处理事件队列的函数。 (因此它处理下一个最低的ID事件)
问题
这在所有经过测试的主要浏览器上也都非常有效。 (在Internet Explorer 8和9,Chrome,Opera和Firefox上进行了测试)由于使用了长时间轮询,因此它也非常灵活。获得所有已发生的事件并保持应用程序完全相同的状态的所有“历史记录”(大多数事件会生成文本数据,并将其附加到页面的某种控制台中)也非常好,即使在重新加载页面之后也是如此。然而,当事件数量变多时,这也成为问题。根据估计,我将需要能够处理多达30,000个事件。在我的测试中,即使在7,000个事件中,情况也开始变差。 Internet Explorer 8堆栈溢出约400个事件。 Chrome不会加载所有事件,但是会关闭(并且中断,但并不总是在同一点,这与IE8不同)。 IE9和FF处理得很好,并且在处理所有事件时挂起2-3秒,这是可以容忍的。但是,我认为这可能只是更多事件破裂之前的问题。我是不是对当前的网络浏览器要求太高,还是我做错了什么?有办法解决吗?我的整个模特是错的吗?
可能的解决方案
我摆弄一些想法,但没有一个真正起作用。我尝试强制后端一次不输出超过200个事件,并在所有当前队列都已处理完毕后添加新的轮询请求。仍然有堆栈溢出。我还尝试在完成处理后删除eventQueue
对象(即使当时为空)并重新创建它,以希望它可以释放一些底层内存或其他东西。我缺少创意,因此任何创意,指针或一般建议都将不胜感激。
编辑:
我有一个启示!我想我完全知道为什么所有这些事情都会发生(但是我仍然不确定如何处理和修复它),我还将提供一些基本的代码摘录。
var eventQueue = new Object();
var processingEvent = false;
var lastRetrievedEventId = 0;
var currentEventId = 0;
function sendPoll() {
// Standard jsonp request (to a intentionally slow backend, i.e. long-polling),
// callback set to pollCallback(). Provide currentEventId to the server to only get
// the events starting from that point.
}
function pollCallback( data ) {
// Make sure the data isn't empty, this happens if the jsonp request
// expires (30s in my case) and it didn't get any new data.
if( !jQuery.isEmptyObject( data ) )
{
// Add each new event to the event queue.
$.each(data.events, function() {
eventQueue[ this.id ] = this;
lastRetrievedEventId = this.id; // Since we just put the event in the queue, we know it is officially the last one "retrieved".
});
// Process the next event, we know there has to be at least one in queue!
processNextEvent();
}
// Go look for new events!
sendPoll();
}
function processNextEvent() {
// Do not process events if they are currently being processed, that would happen
// when an event contains an asynchronous function, like an AJAX call.
if( !processingEvent )
{
var nextEventId = currentEventId + 1;
// Before accessing it directly, make sure the "next event" is in the queue.
if( Object.prototype.hasOwnProperty.call(eventQueue, nextEventId) )
{
processingEvent = true;
processEvent( eventQueue[ nextEventId ] );
}
}
}
function processEvent( event ) {
// Do different actions based on the event type.
switch( event.eventType ) {
case SOME_TYPE:
// Do stuff pertaining to SOME_TYPE.
eventComplete( event );
break;
case SOME_OTHER_TYPE:
// Do stuff pertaining to SOME_OTHER_TYPE.
eventComplete( event );
break;
// Etc. Many more cases here. If there is an AJAX call,
// the eventComplete( event ) is placed in the success: callback
// of that AJAX call, I do not want events to be processed in the wrong order.
}
}
function eventComplete( event ) {
// The event has completed, time to process the event after it.
currentEventId = event.id; // Since it was fully processed, it is now the most current event.
delete eventQueue[ event.id ]; // It was fully processed, we don't need it anymore.
processingEvent = false;
processNextEvent(); // Process the next event in queue. Most likely the source of all my woes.
}
function myApplicationIsReady() {
// The DOM is fully loaded, my application has initiated all its data and variables,
// start the long polling.
sendPoll();
}
$(function() {
// Initializing my application.
myApplicationIsReady();
});
myApplicationIsReady() -> sendPoll()
pollCallback() -> [ processNextEvent() -> processEvent() -> eventComplete() -> processNextEvent() ]
pollCallback() -> processNextEvent() -> processEvent() -> eventComplete() -> sendPoll()
最佳答案
不使用递归调用函数,而是使用setTimeout(func, 0)
怎么样?
关于javascript - 事件系统导致Javascript中的堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11399322/
我正在尝试将 WPF CodeBehid 事件(如 Event、Handler、EventSetter)转换为 MVVM 模式。我不允许使用 System.Windows.Controls,因为我使用
我可能误解了 Backbone 中的事件系统,但是当我尝试以下代码时什么也没有发生。当我向 Backbone.Events 扩展对象添加新属性时,它不应该触发某种更改、更新或重置事件吗?就像模型一样吗
我遇到了一个简单的问题,就是无法弄清楚为什么它不起作用。我有一个子组件“app-buttons”,其中我有一个输入字段,我想听,所以我可以根据输入值过滤列表。 如果我将输入放在我有列表的根组件中,一切
System.Timers.Timer 的 Elapsed 事件实际上与 System.Windows.Forms.Timer 的 Tick 事件相同吗? 在特定情况下使用其中一种比使用另一种有优势吗
嗨,这个 javascript 代码段是什么意思。(evt) 部分是如此令人困惑.. evt 不是 bool 值。这个怎么运作? function checkIt(evt) { evt
我正在使用jquery full calendar我试图在事件被删除时保存它。 $('calendar').fullCalendar ({
我有两个链接的鼠标事件: $('body > form').on("mousedown", function(e){ //Do stuff }).on("mouseup", function(
这是我的代码: $( '#Example' ).on( "keypress", function( keyEvent ) { if ( keyEvent.which != 44 ) {
我尝试了 dragOver 事件处理程序,但它没有正常工作。 我正在研究钢琴,我希望能够弹奏音符,即使那个键上没有发生鼠标按下。 是否有事件处理程序? 下面是我正在制作的钢琴的图片。 最佳答案 您应该
当悬停在相邻文本上时,我需要使隐藏按钮可见。这是通过 onMouseEnter 和 onMouseLeave 事件完成的。但是当点击另外的文本时,我需要使按钮完全可见并停止 onMouseLeave
我有ul标签内 div标签。我申请了mouseup事件 div标记和 click事件 ul标签。 问题 每当我点击 ul标签,然后都是 mouseup和 click事件被触发。 我想要的是当我点击 u
我是 Javascript 和 jQuery 的新手,所以我有一个非常愚蠢的疑问,请耐心等待 $(document).click(function () { alert("!"); v
我有一个邮政编码解析器,我正在使用 keyup 事件处理程序来跟踪输入长度何时达到 5,然后查询服务器以解析邮政编码。但是我想防止脚本被不必要地调用,所以我想知道是否有一种方法可以跟踪 keydown
使用事件 API,我有以下代码来发布带有事件照片的事件 $facebook = new Facebook(array( "appId" => "XXX", "se
首次加载 Microsoft Word 时,既不会触发 NewDocument 事件也不会触发 DocumentOpen 事件。当 Word 实例已打开并打开新文档或现有文档时,这些事件会正常触发。
我发现了很多相关问题(这里和其他地方),但还没有具体找到这个问题。 我正在尝试监听箭头键 (37-40) 的按键事件,但是当以特定顺序使用箭头键时,后续箭头不会生成“按键”事件。 例子: http:/
给定的 HTML: 和 JavaScript 的: var $test = $('#test'); $test.on('keydown', function(event) { if (eve
我是 Node.js 的新手,希望使用流运行程序。对于其他程序,我必须同时启动一个服务器(mongodb、redis 等),但我不知道我是否应该用这个运行一个服务器。请让我知道我哪里出了问题以及如何纠
我正在尝试使用 Swift 和 Cocoa 创建一个适用于 OS X 的应用程序。我希望应用程序能够响应关键事件,而不将焦点放在文本字段上/文本字段中。我在 Xcode 中创建了一个带有 Storyb
我有以下代码: (function(w,d,s,l,i){ w[l]=w[l]||[];w[l].push({
我是一名优秀的程序员,十分优秀!