setInterval By the minute On the minute

霸气de小男生 提交于 2019-12-21 07:11:09

问题


To the javascript enthusiasts,

how would you program a setTimeOut (or setInterval) handle to fire by the minute on the minute. So for example, if it is the 51 second of the current time, then fire it in 9 seconds, if it is the 14th second then fire it in 46 seconds

thanks


回答1:


var date = new Date();

setTimeout(function() {
    setInterval(myFunction, 60000);
    myFunction();
}, (60 - date.getSeconds()) * 1000);

Obviously this isn't 100% precise, but for the majority of cases it should be sufficient.




回答2:


var nextTick = function() {
  return 60000 - (new Date().getTime() % 60000);
}, timerFunction = function() {
  // do stuff
  // do stuff
  // do stuff
  setTimeout(timerFunction, nextTick());
};
var timeout = setTimeout(timerFunction, nextTick());



回答3:


First, let's make sure we know how much time do we have until the next minute:

var toExactMinute = 60000 - (new Date().getTime() % 60000);

Now, if you want to work with setTimeout, then

setTimeout(yourfunction, toExactMinute);

If you want to do a setInterval:

setTimeout(function() {
    setInterval(yourFunction, 60000);
    yourFunction();
}, toExactMinute);



回答4:


At first, I used the solution proposed by Joel Potter. His solution is good enough in most cases. However, because the javascript is doing one thing at a time (unless you are using Workers), it may be late with first timeout, so your first timeout is executed eg. 5 seconds too late and you get interval on every 5 seconds after the minute.

So, here is my implementation:

function setMyFunctionInterval()
{
    var currentDateSeconds = new Date().getSeconds();
    if (currentDateSeconds == 0) {
        setInterval(myFunction, 60000);
    }
    else {
        setTimeout(function () {
            setMyFunctionInterval();
        }, (60 - currentDateSeconds) * 1000);
    }

    myFunction();
}

setMyFunctionInterval();



回答5:


var seconds = (new Date()).getSeconds();

Use 60-seconds as the timeout time. Granted, setTimeout lets you specify milliseconds, which means you should also be checking milliseconds, but this will give you "close enough" for most applications. If anything, this should make you overshoot the minute some fraction of a second, but it's better to overshoot than undershoot. Undershooting would cause catastrophic failure with this method.




回答6:


var d = new Date();
var milisecondsUntilMinuteChanges = 60000 - d.getMilliseconds() - (1000 * d.getSeconds());



回答7:


function waitForNewMinute() {
    if (new Date().getSeconds()>1) {
        setTimeout(waitForNewMinute, 500);
    } else {
        setInterval(doMyThing,60000);
    } 
}

waitForNewMinute();



回答8:


Although too late for the response, I have had similar problem to solve recently and thought of sharing my approach. My problem was to run a timeout after a specified seconds based on how far it is away from a minute, and subsequently run interval function each minute. Here is what I did.

Let's say the date is javascript date object created using date = new Date();

  1. Get the seconds left to reach a minute secondsLeft = 60 - date.getSeconds();
  2. Then set a timeout function to run after secondsLeft, and inside the function set an interval function to run each minute as:

    setTimeout(function() {
      // perform the action **A**;
      minuteMS = 60 * 1000; // seconds * milliSeconds
      setIntervalId = setInterval(function() {
      // perform the action **A**;
     }, minuteMS);
    }, secondsLeft);
    
  3. Using above format/algorithm you should be able to achieve similar problems be the seconds supplied in any format. The idea is to get the difference of seconds and 60, run a timeout after those seconds, and inside timeout function run interval function with interval as a minute/or anything as such based on requirement.



回答9:


I used the ' (60 - date.getSeconds()) * 1000);' method on a data refresh function and, while it worked, it 'drifted' over time (14 seconds late before I changed it!)

As the data needed to be updated ON the minute (and that was obviously not happening as we have a clock on the same page!), here's the solution I came up with:

setInterval(function () {
    if(moment().format('ss') === "00"){
        console.log('we are at the 0 - update the data!');
        refresh_data();
    }
}, 1000);

This of course uses moment.js to find the '0' time and it certainly does what the OP asked - fires on the minute - every time!




回答10:


I believe all the answers are flawed. Once you have started the setInterval, the interval time cannot be changed without creating a new setInterval object. So you will only use the initial calculated time for each iteration. You can create new setInterval objects, but that has to be costly.

See: How do I reset the setInterval timer?

My recommendation is to create a looping function that utilizes the setTimeout instead.

Here's some code:

var duration = 5; //in minutes. This is just to control the total length
var startTime = new Date().getTime(); //must be in milliseconds

function myOnTheMinuteTimer(){
    setTimeout(function(){
        var currentTimeMS = new Date().getTime();
        var diffMs = Math.abs(startTime - currentTimeMS);
        diffMs = diffMs/1000; //take out the milliseconds
        var seconds = Math.floor(diffMs % 60);
        diffMs = diffMs/60;
        var minutes = Math.floor(diffMs % 60);
        var minutesLeft = duration - minutes;
        console.log("Time passed:", minutes + "m :" + seconds + "s");

        if(minutes <= duration){
            console.log("Timer expired.");
        } else {
            myOnTheMinuteTimer();   
        }
    }, setIntervalTimeToNextMinute());
}


//Initialize timer
myOnTheMinuteTimer();


//Get our time until the next minute
function setIntervalTimeToNextMinute(){
    var currentDateSeconds = new Date().getSeconds();
    if(currentDateSeconds == 0){
        return 60000;
    } else {
        return (60 - currentDateSeconds) * 1000;
    }
}

My use case for this was a session timout:

startTime - allows me to pass in any milliseconds time. This way I can avoid lapses in page loading. Say user logins in at a certain time. I capture that time, then pass it into initial function and it will adjust back to the on minute calculation.

duration - I use the duration check for a timeout setting. If the application has a 20 minute timeout, then I need to route the user to the login screen.

optionally - you can add more variations. Say you wish to give the user a 2 minute warning that they will be logged out. Simply add to the conditional an else if for 2 minutes.

Hope that helps! Happy coding!



来源:https://stackoverflow.com/questions/2579762/setinterval-by-the-minute-on-the-minute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!