我经常遇到以下情况,所以我想知道是否有内置的 jQuery 方法来解决这个问题。
想象一下下面的代码:
$(document).click(function() {
paintCanvas();
});
此代码的问题在于,如果用户快速连续点击屏幕 50 次,您将调用 50 次 paintCanvas 使浏览器过载。
如果 paintCanvas 当前正在执行并且创建了一个新请求,我们希望将新请求排队,以便它等到 paintCanvas 完成执行。然而,与此同时,我们可以放弃任何先前排队的对 paintCanvas 的调用,因为我们只关心鼠标的最终状态,而不是所有中间状态。
下面是一些解决问题的代码:
var _isExecuting, _isQueued;
function paintCanvas() {
if (_isExecuting) {
if (!_isQueued) {
_isQueued = true;
setTimeout(function() {
_isQueued = false;
paintCanvas();
}, 150);
}
return;
}
_isExecuting = true;
// ... code goes here
_isExecuting = false;
};
This AJAX queue plugin实质上实现了此功能,但仅在 AJAX 方面实现。当然,这是一个非常普遍的问题,可以用更通用的方式解决?
最佳答案
您不必使用mousemove
来解决这个问题,因为系统已经为您完成了。当 paintCanvas
正在执行时,即使鼠标正在剧烈移动,它也不会生成数百个 mousemove 事件。相反,下一个事件将是鼠标的当前位置,而不是所有干预鼠标事件的队列。
看看这个 jsFiddle:http://jsfiddle.net/jfriend00/4ZuMn/ .
在 body (下部,右 Pane )中尽可能快地摆动鼠标。然后将鼠标移出 Pane 并注意计数立即停止 - 不再有鼠标事件。它永远不会叠加鼠标事件。每当系统为下一个鼠标事件做好准备时,它就会获取鼠标的最新位置。单个鼠标移动不会排队 - 它们不会累积。您还可以在鼠标事件列表中看到许多中间鼠标事件不存在(例如,许多坐标丢失),即使鼠标经过了更多位置。这是因为当鼠标处于该位置时系统尚未准备好进行鼠标事件,因此跳过了该位置。
此外,因为 javascript 是单线程的,所以当您当前正在处理一个鼠标事件时,您永远不会得到一个新的鼠标事件。在您处理完您已经拥有的那个之前,系统不会生成一个新的。因此,您永远不会在代码中的 javascript 中看到 _isExecuting
为 true
。你根本不需要那张支票。而且,由于您不需要该检查并且它永远不会为真,因此您的任何排队代码都不会执行。您可以在这个 jsFiddle 中看到,您永远无法捕获重新输入的 mousemove 事件:http://jsfiddle.net/jfriend00/ngnUT/ . inAction 标志永远不会被捕获为真,无论您将鼠标摆动多快或多远。
关于javascript - 在 Javascript 中,如果函数已经在执行,则将函数的执行排队,但取消任何先前排队的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8753567/