Javascript中组合延迟函数调用

我不太确定这是什么技术术语。 我有一个交互式graphics界面。 在用户与GUI交互之后,我需要执行一些CPU密集型操作。 但是,用户input非常频繁,所以我只想在没有用户input的1000ms之后调用这个函数。 在我使用的模式下面:

scheduler = (function(){ var timer; function exec(call, delay){ clearTimeout(timer); timer = setTimeout(call, delay); }; return exec; })() 

也就是说,如果3个scheduler调用是一个接一个完成的,那么只有最后一个调用scheduler会被执行:

 scheduler(function(){alert('foo')}, 1000); scheduler(function(){alert('bar')}, 1000); scheduler(function(){alert('zoo')}, 1000); 

它似乎工作,但感觉有点哈克我有点担心Javascript setTimeout任何警告,特别是范围的问题。 这看起来像是我可以在更大规模上使用的可靠模式吗? 我调用scheduler的内联函数是否可以像往常一样在其词法范围内查找所有对象,何时由settimeout调用? 如果我有几个这样的调度器实例呢? 他们能互相干扰吗? 有没有其他办法来完成这个?

我会做什么:

http://jsfiddle.net/gunderson/4XXQ4/1/

  var severQueue = []; var delay; $("#inputSquare").mousemove(onMouseMove); function onMouseMove(){ if (delay){ clearTimeout(delay); } serverQueue.push("doSomething") delay = setTimeout(sendToServer, 1000); } function sendToServer(){ console.log(serverQueue.length); delay = null; $("#inputSquare").addClass("activated"); // do some ajax using serverQueue // we'll just simulate it with another timeout for (var i in serverQueue){ serverQueue.pop(); } onComplete = setTimeout(onAjaxComplete, 1000); } function onAjaxComplete(){ $("#inputSquare").removeClass("activated"); }​ 

从理论上讲,你的解决scheme看起来像是可行的。 没有与您将调用函数传递callback函数相关的范围问题; callback将closures它创build的任何环境,就像在JavaScript中的任何其他function。 这就是说, 范围规则在JavaScript中可能有点棘手 ,所以请确保你阅读它。

实际上,可能会有一些与setTimeout相关的特定于浏览器的问题,可能导致此解决scheme无法工作。 例如,某些浏览器执行setTimeoutcallback的频率可能会有所不同,因此您将等待的时间比您期望的执行callback的时间要长。 所有setTimeoutcallback将被顺序执行; 他们永远不会被并行执行。 但是,您可以保证执行的顺序是什么。

所有这一切,你的解决scheme的任何重大陷阱可能会有更多的与你注册的callback,而不是你注册的方式。

underscore.js中的debounce 函数完全是这样的:

_.debounce(function, wait, [immediate])

创build并返回传递的函数的新的去抖动版本,该函数将延迟其执行,直到自上次调用后等待几毫秒。 对于实现只有在input停止后才会发生的行为很有用。 例如:渲染Markdown注释的预览,在窗口停止resize后重新计算布局,等等。