我有一个网页(javascript),它有两种类型的事件:
周期性事件忙于200 - 300 ms(它正在启动同步SOAP调用)。
画布事件:
var c=document.getElementById("myCanvas");
c.addEventListener('click', function(e) {alert('Click');},false);
周期性:
var timer1= new Timer(1000,"Refresh()"); // A library call
function Refresh()
{
timer1.stop();
// Synchronous SOAP call would come here
// with the results we draw the canvas again
timer1.start();
}
如果我在进行SOAP调用时单击画布,则不会触发click事件,或者我假设,因为警报未显示。
如果我在定期事件结束后再次点击,再次调用之前,每次点击都会显示警告。
据我所知,如果在执行周期性事件时生成了click事件,则应该将其延迟到另一个事件完成。
可能导致问题的原因是什么?
Pd积。我正在使用Firebug(在Firefox上)知道何时进行SOAP调用。
答案 0 :(得分:3)
同步调用会阻止I / O,因此不会触发警报。由于您正在等待回电,因此在此期间发生的任何操作都将被忽略。
这篇文章可能会有所帮助:http://ejohn.org/blog/how-javascript-timers-work/
由于浏览器中的所有 JavaScript都在单个主题上执行 仅运行异步事件(例如鼠标单击和计时器) 当执行中有一个开放时。
- JavaScript引擎只有一个线程,迫使异步事件排队等待执行。
- setTimeout和setInterval在执行异步代码的方式上有根本的不同。
- 如果atimer被阻止立即执行,它将被延迟到下一个可能的执行点(这将更长 比期望的延迟)。
- 如果间隔时间足够长(超过指定的延迟),间隔可以无延迟地执行。
答案 1 :(得分:1)
因为默认情况下,您在Javascript中执行的UI事件和其他所有操作都会在单个线程上执行,这是您所期望的。但这只是原因......
一旦你理解了原因,你就可以在中途找到解决方案:如果你拥有进行同步SOAP调用,这似乎就是这种情况,你将不得不使用不同的他们的线程。输入网络工作者......
要创建新的Web worker,请调用Worker()构造函数,指定要在worker线程中执行的脚本的URI。
var worker = new Worker('my_task.js');
要接收来自worker的通知,请将worker的onmessage属性设置为适当的事件处理函数。
worker.onmessage = function(event) {
console.log("Called back by the worker!\n");
};
您可以在此处找到更多信息:
http://en.wikipedia.org/wiki/Web_worker
引自上述来源:Safari,Chrome,Opera,Internet Explorer(版本10)和Mozilla Firefox目前支持Web工作者。 Safari for iOS 5以及Android版本2.0和2.1支持Web工作者。
关于Android支持:请参见此处:Why was HTML5 Web Workers support removed from the Android browser in versions 2.2 and up?
有关IO的示例:
https://developer.mozilla.org/en-US/docs/Using_workers_in_extensions
希望这可以帮助您解决问题。
免责声明:一般来说,尝试避免学习如何执行异步通信非常容易,而Web工作者似乎是一种很好的方法。我不是在倡导这种方法,而只是建议解决那些显然没有替代方案的人。一旦您习惯了异步通信就可以非常容易,并且可以帮助您构建更好的网站。 jQuery为异步IO提供了很好的支持。