函数仅在键控事件延迟的情况下执行

Function only being executed with a delay of a keyup event

本文关键字:延迟 情况下 执行 事件 函数      更新时间:2023-09-26

EDIT:我希望在最后一个keyup事件的一秒钟后调用并执行一个函数

这是我的代码:http://jsfiddle.net/gKkAQ/

JS:

function aFunction() {
    setTimeout(function () {
        console.log("1");
    }, 1000);
}
$(document).ready(function () {
    $("#Input").keyup(function () {
        aFunction();
    });
});

HTML:

<input type="text" id="Input"></input>

您可以很容易地运行JSFiddle,并在控制台中看到,无论您键入的速度有多快,函数都将被执行,而不管它以前的执行状态如何(在这种情况下,setTimeout还没有在1秒内完成,但如果您继续键入,则将执行所有函数调用)

"你会看到函数每秒钟都在执行。我希望它在最后一次按键操作的一秒钟后执行"

setTimeout()函数返回一个id,您可以将该id传递给clearTimeout()以防止超时发生——当然,假设您在超时之前调用clearTimeout()

var timeoutId;
function aFunction() {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(function () {
        console.log("1");
    }, 1000);
}
$(document).ready(function () {
    $("#Input").keyup(function () {
        aFunction();
    });
});

使用已经发生的超时id调用clearTimeout()没有害处,在这种情况下没有任何效果。

因此,上面的代码清除了以前的超时(如果有),然后创建了一个新的超时,效果是在用户停止键入后,带有console.log()的匿名函数将只执行1000ms。如果用户在等待超过1000ms后再次开始键入,则会再次排队超时。

注意:这个答案对应于最初的、非常一般的问题,在它被广泛编辑并转换为一个非常具体的问题之前。

这取决于您的确切执行环境。从理论上讲,JavaScript是单线程的。你所描述的情况永远不应该发生。然而,在实践中,确实会发生(尤其是在浏览器内部),并且没有办法完全控制它

最接近"控制"的替代方案是从检查全局"激活计数器"变量的值开始。如果为0,请立即将其递增并继续执行。退出时递减。

为什么这不起作用?因为两次激活可以同时到达测试。由于变量为0,两个测试都将成功,并且都将继续递增变量并执行。与大多数同步/并发问题一样,问题不会系统地发生,而是偶尔随机发生。这使得事情很难检测、复制和纠正。

您可以尝试两次询问变量,如:

if( activationCounter <= 0 ) {
    if( activationCounter <= 0 ) {
        activationCounter++;
        //  Execution
        activationCounter--;
    }
}

在许多圈子里,这被描述为解决问题的方法,但它只会降低冲突的概率(相当大的一部分,但不会降低到零)。这只是对"双重检查锁定"模式理解不周的结果。问题仍然会出现,但频率要低得多。我不确定这是好是坏,因为它们将更加难以检测、复制和纠正。