简体   繁体   English

如何重用此JavaScript超时关闭?

[英]How do I reuse this JavaScript timeout closure?

I found the following piece of JavaScript code (maybe here at Stack Overflow?) for implementing a timeout: 我发现以下JavaScript代码(也许在Stack Overflow上)实现了超时:

var delay = (function() {
  var timer = 0;
  return function(callback, ms) {
    clearTimeout(timer);
    timer = setTimeout(callback, ms);
  };
})();

I'm new to JavaScript, so I'm still trying to wrap my head around closures. 我是JavaScript的新手,所以我仍在尝试把头放在闭包上。 If I call delay(firstCallback, 200) in one place and then delay(secondCallback, 200) right after, the first timeout callback is cleared, while the second callback executes successfully. 如果我在一个地方调用delay(firstCallback, 200) ,然后在之后调用delay(secondCallback, 200) ,则将清除第一个超时回调,而第二个回调将成功执行。

How do I reuse delay in different instances without overwriting other instances? 如何在不同实例中重用delay而不覆盖其他实例? (Not sure if those terms are correct, but hopefully it gets my point across.) So, in the above example, I want both callbacks to execute. (不知道这些术语是否正确,但是希望可以理解我的意思。)因此,在上面的示例中,我希望两个回调都执行。

Thanks for your help! 谢谢你的帮助!

EDIT: As a practical example, I'm trying to buffer keypress events on an input field, so that the callback is only executed after no key has been pressed for 200ms. 编辑:作为一个实际示例,我试图在输入字段上缓冲按键事件,以便仅在200ms内没有按键按下后才执行回调。 But I have multiple input fields, and currently the buffer breaks when two input fields have keypress events in quick succession. 但是我有多个输入字段,当前,当两个输入字段连续快速发生按键事件时,缓冲区就会中断。

To reuse this, it is easier to get rid of the anonymous function and use it as a generator. 要重用它,更容易摆脱匿名函数并将其用作生成器。

var createDelayManager = function() {
  var timer = 0;
  return function(callback, ms) {
     clearTimeout(timer);
     timer = setTimeout(callback, ms);
  };
}


var delayManagerOne = createDelayManager();
delayManagerOne(firstCallback, 200);

var delayManagerTwo = createDelayManager();
delayManagerTwo(secondCallback, 200);

Here is a working fiddle: http://jsfiddle.net/HJrM7/ 这是一个有效的小提琴: http : //jsfiddle.net/HJrM7/

But, It is worth noting, that the point of this closure is to prevent multiple callbacks from getting stacked against some object. 但是,值得注意的是,此关闭的目的是防止针对某个对象堆积多个回调。 It is a really nice closure though that enables you to make sure that the last event triggered will be the one that gets acted on. 尽管这是一个非常不错的闭包,但它使您能够确保触发的最后一个事件将是被执行的事件。 I use this technique a lot to prevent flickering, or unwanted mouse out events during ie redraws. 我经常使用此技术来防止闪烁或在重绘期间发生不必要的鼠标移出事件。

You are looking for 你在找

Delay = function(callback, ms) {
    this.callback = callback;
    this.ms = ms;
};

Delay.prototype = {
    timer: -1,

    restart: function() {
        if (this.timer != -1) clearTimeout(this.timer);
        this.timer = setTimeout(this.callback, this.ms);
    }
};

var delay1 = new Delay(callback1, 100);
var delay2 = new Delay(callback2, 100);

// on some event1
delay1.restart();

// on some event2
delay2.restart();

Example on jsfiddle: http://jsfiddle.net/TF9Tw/1/ jsfiddle上的示例: http : //jsfiddle.net/TF9Tw/1/

The closure holds state that persists between calls of the inner function. 闭包保持内部函数调用之间持续存在的状态。 In this case it is used so there is only one timeout at a time. 在这种情况下,使用它是因为一次只能有一个超时。 If you want multiple timeouts available at a time you may just write 如果您希望一次有多个超时时间,可以写

setTimeout(callback, ms);

edit: 编辑:

For your example, the best solution would be to make an object like this 对于您的示例,最好的解决方案是使像这样的对象

function DelayManager(){}
DelayManager.prototype.timer = 0;
DelayManager.prototype.delay = function(callback, ms) {
  clearTimeout(this.timer);             
  this.timer = setTimeout(callback, ms);   
}
someDelayManager = new DelayManager();

Where instead of someDelayManager you would use a member variable of some object unique per input element. 在每个输入元素中使用某个对象唯一的成员变量来代替someDelayManager。 To add a delay you would then call. 要增加延迟,您可以致电。

someDelayManager.delay(callback, ms);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM