3

タイマー機能があり、タイムアウトをクリアするか機能をリセットしたいのですが、実行するたびに新しいタイムアウトが作成されるため、いくつかのカウントを受け取ります。私の考えは、関数を実行するたびにカウントをリセットすることです。タイマーのインスタンスが1つだけ必要で、正しいカウントを取得します。関数を数回実行する場合は、0 にリスタートします。

これが私のコードです:

var timeouts = new Array();
var timer = null;

io.sockets.on('connection', function (client)
{
    client.on("start", function (){
    console.log('Someone has pressed Start button',new Date().getTime());

        //try to kill all timeouts
        for (var timeout in timeouts) {
            clearTimeout(timeout);
        };

        if(this.timer == null) {
            this.timer = new timer(1000, function (data) {
                io.sockets.emit('timeupdate', data);
            })
        }else {
            this.timer = null;
    });
});


function timer(delay, callback)
{
    // self-reference
    var self = this;

    if (!(this instanceof timer)) {
        return new timer();
    }
    // attributes
    var counter = 0;
    var start = new Date().getTime();

    /**
     * Delayed running of the callback.
     */
    function delayed()
    {
        console.log(counter);
        callback(counter);
        counter ++;
        var diff = (new Date().getTime() - start) - counter * delay;
        var timeOut = setTimeout(delayed, delay - diff);
        timeouts.push(timeOut);
    }

    // start timer
    delayed();
    var timeout = setTimeout(delayed, delay);
    timeouts.push(timeout);
}

前もって感謝します。

4

1 に答える 1

2

使用clearTimeout()するのが正しい方法です。問題はあなたのforループです。これは古典的なループのように見えるかもしれませんforeachが、そうではありません。あなたがしなければなりません:

for (var i=0; i< timeouts.length; i++) {
    clearTimeout(timeouts[i]);
}

あるいは、これも個人的には好きではありません:

for (var i in timeouts) {
    clearTimeout(timeouts[i]); // note how the array is indexed using var i
}

これは、よくある JavaScript の落とし穴です。- for (x in y)loop は、値ではなく、配列のインデックスを実際に反復します。オブジェクトのプロパティを反復処理することもできます。やってみて:

var a = [3, 2, 5, 8];

for (var i in a) {
    console.log(i);
    console.log(a[i]);
}

var o = { test: 'hello', number: 1234 }; 
for (var x in o)
    console.log(x);
于 2013-01-10T09:51:35.363 に答える