我有一个Web应用程序,提交ajax请求(启动IR LED发送数据)onmousedown,并停止onmouseup。一般都有效。
但是,如果一个人快速点击,我会在启动命令之前将停止命令转到LED控制器。我添加了跟踪订单的代码,实际的事件提交(在XMLHttpRequest上打开)的顺序正确(并且它们是异步的)。然后我检测了onstatechange以记录每个状态和发生状态更改时的时间戳,并且我看到偶尔发生的(0)和服务器连接初始化(1)状态以正确的顺序发生,“收到”( 2)随后的状态发生故障。
我的第一个问题是这些事件是否支持在提交的订单中发生?
如果是这样,任何想法可能导致他们不这样做?
如果处理顺序不确定,有没有办法强制它(没有建立我自己的队列,只允许一个ajax调用是杰出的,这是一个油漆)?
为了演示此问题(使用Windows 8.1和Chrome 39.0.2171.71m上的客户端以及IE 11.0.14,运行php 5.4.4-14 + deb7u11和Apache / 2.2.22的覆盆子pi上的服务器),这里是从一系列事件中捕获的日志。它很小而且有点模糊,所以我尝试对每次点击进行颜色编码(绿色,蓝色,橙色顺序),状态代码在第3列。一旦达到状态2,注意向上(以黄色突出显示)在第三次单击中向下。
接下来是提交它的代码。我相信很多事情与问题无关,但我要包括它以防万一。注意“RemoteFunc”既可以在mouseup和mousedown上调用,也可以在(对于单独的对象)上单击,但每个都有不同的func,然后执行POST。每个对象使用mouseup / mousedown或onclick,而不是两者。
帖子的处理时间很容易大于鼠标点击的持续时间,因此在第一个“向下”或“向上”完成之前出现新的“向下”并不意外,但问题是我希望他们按顺序处理。事实上,它们似乎按顺序提交并按顺序启动(转到状态1),但是无序接收,所以我假设ajax正在创建多个连接,并且对这些连接的响应正在失序。
这使我怀疑订单无法保证。但我没有找到任何确认的东西(除了没有保证是有秩序的)。
除手动构建队列和单个流请求之外的任何简单解决方案?
function RemoteFunc(str,func)
{
var xmlhttp=new XMLHttpRequest();
if(event.button!=0)
{
AddMessageEntry(str + " dismissed - not left click",true);
return true; //Only respond to left mouse down so context menus do not fire click and cause a competing event
}
if(taskrunning!="")
{
AddMessageEntry(str + " ignored, " + taskrunning + " already running",false);
return true;
}
if(func=="remoteup.cgi") { updown=" mouse-up"; }
else if (func=="remotedown.cgi") { updown=" mouse-down"; }
else { updown=""; }
AddMessageEntry(str + updown + " Started",true);
xmlhttp.onreadystatechange=function()
{
// if (xmlhttp.readyState==4)
// {
if(func=="remoteup.cgi") { updown=" mouse-up"; } // because this can run in overlapping functions we need to recalculate this here
else if (func="remotedown.cgi") { updown=" mouse-down"; }
else { updown=""; }
AddMessageEntry(str + updown + " " + states[xmlhttp.readyState] + " " + xmlhttp.responseText,false);
if(xmlhttp.readyState==4) {taskrunning="";}
// }
}
if(event.type.toString()=="click") // We only need to track running tasks invoked with a click -- mousedown/up are async since they run continually (from down) until stopped (from up)
{
taskrunning=str;
}
xmlhttp.open("POST","cgi-bin/" + func + "?Button="+str,true);
xmlhttp.send();
}