-2

编辑:我希望在最后一个 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 秒内完成,但如果您继续键入,将执行所有函数调用)

4

2 回答 2

3

“您将看到该功能每秒都在执行。我希望它在最后一次按键操作的一秒后执行”

setTimeout()函数返回一个 id,您可以将其传递给它clearTimeout()以防止发生超时 - 当然假设您clearTimeout()在时间结束之前调用。

var timeoutId;
function aFunction() {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(function () {
        console.log("1");
    }, 1000);
}

$(document).ready(function () {
    $("#Input").keyup(function () {
        aFunction();
    });
});

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

所以上面的代码清除了之前的超时时间(如果有的话),然后创建一个新的超时时间,这样匿名函数console.log()只会在用户停止输入后 1000ms 执行。如果用户在等待超过 1000 毫秒后再次开始输入,则会排队另一个超时。

于 2013-08-18T05:44:26.440 回答
0

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

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

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

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

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

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

在许多圈子中,这被描述为问题的解决方案,但它只会降低冲突的可能性(相当多,但不是零)。这只是对“双重检查锁定”模式理解不佳的结果。问题仍然会发生,但频率要低得多。我不确定这是好是坏,因为它们将更难以检测、复制和纠正。

于 2013-08-18T05:21:21.333 回答