19

Javascriptのwindow.setTimeout(および関連するsetInterval)関数を使用すると、将来実行される関数をスケジュールできます。

id = setTimeout(function, delay);

ここで、「delay」は、関数を呼び出す未来のミリ秒数です。この時間が経過する前に、次を使用してタイマーをキャンセルできます。

clearTimeout(id);

私が欲しいのはタイマーを更新することです。関数が最初にスケジュールされたよりもxミリ秒早くまたは遅く呼び出されるように、タイマーを進めたり遅らせたりできるようにしたい。

getTimeoutメソッドがある場合は、次のようにすることができます。

originally_scheduled_time = getTimeout(id);
updateTimeout(id, originally_schedule_time + new_delay);  // change the time

しかし、私が知る限り、getTimeoutや既存のタイマーを更新する方法は他にありません。

スケジュールされたアラームのリストにアクセスして変更する方法はありますか?

より良いアプローチはありますか?

ありがとう!

4

5 に答える 5

14

この種の機能が本当に必要な場合は、自分で作成する必要があります。

setTimeout呼び出しのラッパーを作成できます。これにより、タイマーを「延期」するために使用できるオブジェクトが返されます。

function setAdvancedTimer(f, delay) {
  var obj = {
    firetime: delay + (+new Date()), // the extra + turns the date into an int 
    called: false,
    canceled: false,
    callback: f
  }; 
  // this function will set obj.called, and then call the function whenever
  // the timeout eventually fires.
  var callfunc = function() { obj.called = true; f(); }; 
  // calling .extend(1000) will add 1000ms to the time and reset the timeout.
  // also, calling .extend(-1000) will remove 1000ms, setting timer to 0ms if needed
  obj.extend = function(ms) {
    // break early if it already fired
    if (obj.called || obj.canceled) return false; 
    // clear old timer, calculate new timer
    clearTimeout(obj.timeout);
    obj.firetime += ms;
    var newDelay = obj.firetime - new Date(); // figure out new ms
    if (newDelay < 0) newDelay = 0;
    obj.timeout = setTimeout(callfunc, newDelay);
    return obj;
  };
  // Cancel the timer...  
  obj.cancel = function() {
    obj.canceled = true;
    clearTimeout(obj.timeout);
  };
  // call the initial timer...
  obj.timeout = setTimeout(callfunc, delay);
  // return our object with the helper functions....
  return obj;
}

var d = +new Date();
var timer = setAdvancedTimer(function() { alert('test'+ (+new Date() - d)); }, 1000);

timer.extend(1000);
// should alert about 2000ms later
于 2009-12-24T07:23:38.277 に答える
4

私は信じていません。より良いアプローチは、タイマー(func-ref、delay、timestamp)を格納する独自のラッパーを作成することです。そうすれば、タイマーをクリアしてタイマーを更新するふりをして、更新された遅延でコピーを計算できます。

于 2009-12-24T07:08:02.990 に答える
2

別のラッパー:

function SpecialTimeout(fn, ms) {
    this.ms = ms;
    this.fn = fn;
    this.timer = null;
    this.init();
}

SpecialTimeout.prototype.init = function() {
    this.cancel();
    this.timer = setTimeout(this.fn, this.ms);
    return this;
};

SpecialTimeout.prototype.change = function(ms) {
    this.ms += ms;
    this.init();
    return this;
};

SpecialTimeout.prototype.cancel = function() {
    if ( this.timer !== null ) {
        clearTimeout(this.timer);
        this.timer = null;
    }
    return this;
};

使用法:

var myTimer = new SpecialTimeout(function(){/*...*/}, 10000);

myTimer.change(-5000); // Retard by five seconds
myTimer.change(5000); // Extend by five seconds
myTimer.cancel(); // Cancel
myTimer.init(); // Restart

myTimer.change(1000).init(); // Chain!
于 2009-12-24T08:42:39.350 に答える
0

それはあなたが望むものとは正確に一致しないかもしれませんが、とにかく見てください、多分あなたはあなたの利益のためにそれを使うことができます。

必要に応じてタイムアウトを停止および開始できる特別なハンドラー関数を作成できる、私の元同僚によって書かれた優れたソリューションがあります。これは、ホバーイベントにわずかな遅延を作成する必要がある場合に最も広く使用されます。マウスオーバーメニューを非表示にしたい場合のように、マウスがマウスを離れたときではなく、数ミリ秒後に表示します。ただし、マウスが戻ってきた場合は、タイムアウトをキャンセルする必要があります。

解決策は、 getDelayedHandlersと呼ばれる関数です。たとえば、メニューを表示および非表示にする関数があります

function handleMenu(show) {
    if (show) {
        // This part shows the menu
    } else {
        // This part hides the menu
    }
}

次に、次のようにして、遅延ハンドラーを作成できます。

var handlers = handleMenu.getDelayedHandlers({
    in: 200, // 'in' timeout
    out: 300, // 'out' timeout
});

handlers呼び出されたときにもう一方のタイムアウトをキャンセルする2つのハンドラー関数を含むオブジェクトになります。

var element = $('menu_element');
element.observe('mouseover', handlers.over);
element.observe('mouseout', handlers.out);

PSこのソリューションを機能させるには、関数でFunctionオブジェクトを拡張する必要があります。これはPrototypecurryで自動的に実行されます。

于 2009-12-24T07:39:40.280 に答える
-2

1つの可能性は次のようになります。

if (this condition true)
{
  setTimeout(function, 5000);
}
elseif (this condition true)
{
  setTimeout(function, 10000);
}
else
{
  setTimeout(function, 1000);
}

条件やロジックをどのように構築するかはあなた次第です。ありがとう

于 2009-12-24T07:04:47.183 に答える