8

問題

delay2147483648 ミリ秒 (24.8551 日) を超える場合、関数はすぐに起動します。

setTimeout(function(){ console.log('hey') }, 2147483648) // this fires early
setTimeout(function(){ console.log('hey') }, 2147483647) // this works properly

Chrome v26 と Node.js v8.21 で試してみました

4

2 に答える 2

10

32 ビットに制限されているため、次のように再帰関数で setTimeout をラップするだけです。

function setLongTimeout(callback, timeout_ms)
{

 //if we have to wait more than max time, need to recursively call this function again
 if(timeout_ms > 2147483647)
 {    //now wait until the max wait time passes then call this function again with
      //requested wait - max wait we just did, make sure and pass callback
      setTimeout(function(){ setLongTimeout(callback, (timeout_ms - 2147483647)); },
          2147483647);
 }
 else  //if we are asking to wait less than max, finally just do regular setTimeout and call callback
 {     setTimeout(callback, timeout_ms);     }
}

これはそれほど複雑ではなく、1.7976931348623157E+10308 である JavaScript 番号の制限まで拡張可能である必要があります。

setLongTimeout を実行できるようにするには、参照によって渡されるオブジェクトを受け入れるように関数を変更し、呼び出し元の関数にスコープを保持することができます。

function setLongTimeout(callback, timeout_ms, timeoutHandleObject)
{
 //if we have to wait more than max time, need to recursively call this function again
 if(timeout_ms > 2147483647)
 {    //now wait until the max wait time passes then call this function again with
      //requested wait - max wait we just did, make sure and pass callback
      timeoutHandleObject.timeoutHandle = setTimeout(function(){ setLongTimeout(callback, (timeout_ms - 2147483647), timeoutHandleObject); },
          2147483647);
 }
 else  //if we are asking to wait less than max, finally just do regular setTimeout and call callback
 {     timeoutHandleObject.timeoutHandle = setTimeout(callback, timeout_ms);     }
}

これで、タイムアウトを呼び出して、必要に応じて後でキャンセルできます。

var timeoutHandleObject = {};
setLongTimeout(function(){ console.log("Made it!");}, 2147483649, timeoutHandleObject);
setTimeout(function(){ clearTimeout(timeoutHandleObject.timeoutHandle); }, 5000);
于 2013-05-01T15:34:28.457 に答える