javascript - 在 Javascript 中,如果函数已经在执行,则将函数的执行排队,但取消​​任何先前排队的

标签 javascript jquery

我经常遇到以下情况,所以我想知道是否有内置的 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 中看到 _isExecutingtrue。你根本不需要那张支票。而且,由于您不需要该检查并且它永远不会为真,因此您的任何排队代码都不会执行。您可以在这个 jsFiddle 中看到,您永远无法捕获重新输入的 mousemove 事件:http://jsfiddle.net/jfriend00/ngnUT/ . inAction 标志永远不会被捕获为真,无论您将鼠标摆动多快或多远。

关于javascript - 在 Javascript 中,如果函数已经在执行,则将函数的执行排队,但取消​​任何先前排队的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8753567/

相关文章:

javascript - jquery html(array) 不会插入数组中的所有项目

javascript - 嵌套 HTML5 <template> 标签

javascript - Bootstrap 4 条纹表 - 添加行和重绘条纹

javascript - 提交前验证 "select"下拉列表

jquery - 使用缓动切换 div

php - 在产品预览 slider 上显示图像

javascript - 获取 IFRAME 相对于窗口的位置

javascript - Flowtype:动态扩展类

javascript - 当有多个按钮、视频时播放特定视频文件

jquery - 选中/取消选中 - ifChecked 不起作用