17

JS コードを 1 時間ごとに実行したいと考えています。でも使えない

setInterval("javascript function",60*60*1000);

1 時間ごとに実行したいので、つまり 1:00、2:00、3:00 などです。私は何かについて考えています

var d;
while(true) {
  d = new Date();
  if ((d.getMinutes() == '00') && (d.getSeconds() == '00')){
    // my code here
  }  
}

しかし、遅すぎてうまく機能しません。

アイデアをありがとう

4

17 に答える 17

10

できることは、1 分ごとに間隔を空けて実行し、その時間が:00実際のコードを実行する前かどうかを確認することです。

于 2012-09-06T22:03:10.340 に答える
4

以下の関数のようなものを使用できます。これは、ニーズに非常に簡単に適応できます。

次の間隔までの時間を計算し、毎回実行された後にスクリプトを再実行します(3 番目の引数を true に設定しない限り)

function runOnInterval(interval_in_ms, function_to_run, only_run_once = false){
    setTimeout(()=>{
        function_to_run();
        if (!only_run_once) runOnInterval(...arguments);
    }, interval_in_ms - ((Date.now() - (new Date().getTimezoneOffset() * 6e4)) % interval_in_ms));
}

使用例:

// Every day at midnight:
runOnInterval(24 * 60 * 60 * 1000, my_function_to_run);
// Every hour on the hour:
runOnInterval(60 * 60 * 1000, my_function_to_run);
// Every minute on the minute:
runOnInterval(60000, my_function_to_run);
// Every 10 seconds on the 10 second mark:
runOnInterval(1e4, ()=>console.log('this will be run every 10 seconds on the 10 second mark'));
于 2019-07-01T00:43:19.343 に答える
4

ES6 バージョンは、NodeJS および最新のブラウザーで動作します。ブラウザーまたはサーバーのクロックに従ってミリ秒単位で実行されます。

関数:

const doSomething = (something) => {
  let running = true
  let nextHour = () => {
    return 3600000 - new Date().getTime() % 3600000
  }
  let nextCall = setTimeout(() => {
    something()
    doSomething(something)
  }, nextHour())
  return {
    next() { return running ? nextHour() : -1 },
    exec() { something() },
    stop() {
      clearTimeout(nextCall)
      running = false
    },
    start() {
      clearTimeout(nextCall)
      nextCall = setTimeout(() => {
        something()
        doSomething(something)
      }, nextHour())
      running = true
    }
  }
}

使用法:

// Do something at next full hour and repeat forever
doSomething(() => console.log('Full hour reached!'))

// Do something every full hour & stop it
let obj = doSomething(() => console.log('Will I ever execute? :/'))
obj.next() // Time to next execution in milliseconds
obj.next() / 1000 // Time to next execution in seconds
obj.next() / 1000 / 60 // Time to next execution in minutes
obj.stop() // Stop executing every full hour
obj.start() // Continue executing every hour
obj.exec() // Execute now
于 2019-11-08T13:36:31.993 に答える
3

毎回間隔をクリアして設定することでそれを行うことができます。間隔が 1 時間ではなく、1 時間から現在の分と秒を引いたものになります。

var d = new Date();
var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
var intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );

function myFn() {
    // do stuff
    // ...
    clearInterval( intervalId );
    intervalId = setInterval( myFn, 60*60*1000 );
}

これに関する唯一の問題は、最終的にはおそらくドリフトし始めることです...それに対する解決策は、関数を開始するときと同じことを関数内で行うことです:

var d = new Date();
var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
var intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );

function myFn() {
    // do stuff
    // ...
    clearInterval( intervalId );
    var d = new Date();
    var secondsPastHour = d.getMinutes()*60 + d.getSeconds();
    intervalId = setInterval( myFn, 60*60*1000 - secondsPastHour*1000 );
}

これは、毎分更新される概念実証です (コードをテストするために 1 時間も待ちたくありませんでした!): http://jsfiddle.net/dRsua/

于 2012-09-06T22:14:38.057 に答える
1

マークの回答に基づいて、これも探していたので、次のように書きました。

function callEveryFullHour() {

    var now = new Date();
    var nextHour = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours() + 1, 0, 0, 0);
    var difference = nextHour - now;

    window.setTimeout(function(){

        // code goes here

        console.log("It's a full hour!")
        callEveryFullHour();

    }, difference);

}
于 2015-09-18T05:13:28.880 に答える
1

setInterval 関数を毎分 (またはタイマーの精度に応じて毎秒) 実行し、分がゼロになったときにコードを実行する必要があります (ところで get minutes は 0 から 59 までの数値を返します)。

 function myTimer() {
        var d = new Date()
        if (d.getMinutes() == 0) {
        console.log("full hour");
        }
}

 timer = setInterval(function(){myTimer()},60000)

1 時間ごとに設定した後、1 秒ごとに間隔を実行したくない場合は、新しい 1 時間ごとの間隔をトリガーして、最初の間隔をクリアするだけです。

var myHourlyTimer = null;

     function myTimer() {
            var d = new Date()
            if (d.getMinutes() == 0) {
            console.log("full hour");
myHourlyTimer = setInterval(function(){myHourlyTimerFunction()},3600000);
clearInterval(timer)
            }
    }

 timer = setInterval(function(){myTimer()},60000)
于 2012-09-06T22:13:40.460 に答える
0

簡単な方法の 1 つは、チェックを継続的に実行して、時間の変更を検出することです。

var lastProcessedHour = -1;

setInterval(function() {
   var d = new Date();
   var currentHour = d.getHours();
   if (currentHour != lastProcessedHour) {
      // do stuff
      console.log("new hour");

      lastProcessedHour = currentHour;
   }
}, 1000);

上記のように毎秒実行すると、スクリプトは遅くとも新しい時間に 1 秒をトリガーします。

この方法は堅牢で理解しやすいと思います。パフォーマンスの観点からは、この単純なチェックを 1 秒に 1 回実行することは実際には問題にならないはずです。

于 2012-09-06T22:28:02.590 に答える