Is it possible to ser a function to start in a given date and hour? How?
I thought about setTimeout, but what's the maximum time I can set?
--update
By the way, it's for a desktop application.
I agree with JCOC611 - if you can make sure that your application does not close, then just get a Date object of when your alarm should go off and do something like this:
window.setTimeout(function() { soundAlarm() },
alarmDate.getTime() - new Date().getTime());
I see no reason for this not to work, but a lot of people exalt a timer based solution where you have a short lived timer that ticks until the set time. It has the advantage that the timer function can also update a clock or a countdown. I like to write this pattern like this:
(function(targetDate) {
if (targetDate.getTime() <= new Date().getTime()) {
soundAlarm();
return;
}
// maybe update a time display here?
window.setTimeout(arguments.callee,1000,targetDate); // tick every second
})(alarmDate);
This is basically a function that when called with a target date to sound an alarm on, re-calls itself every second to check if the time has not elapsed yet.
setTimeout(functionToCall,delayToWait)
As stated in Why does setTimeout() "break" for large millisecond delay values?, it uses a 32 bit int to store the delay so the max value allowed would be 2147483647
Does setTimeout() have a maximum?
http://www.highdots.com/forums/javascript/settimeout-ecma-166425.html
It may surprise you that setTimeout is
not covered by an ECMA standard, nor
by a W3C standard. There are some
holes in the web standards. This is
one of them. I'm looking to the WHAT
Working Group to fix this. See
http://www.whatwg.org/specs/web-apps/current-work/
There doesn't seem to be a problem in
setting the timeout value to something
that is vastly greater than the MTBF
of the browser. All that means is that
the timeout may never fire.
http://javascript.crockford.com/
-Douglas Crockford
As others have mentioned, this isn't the way to handle the situation. Use setTimeout to check a date object and then fire the event at the appropriate time. Some code to play with is linked below.
http://www.w3schools.com/js/tryit.asp?filename=tryjs_timing_clock
You should not relay on setTimeout for the actual alarm trigger but for a periodic function tracking the alarm. Use setTimeout to check the stored time for your alarm say every minute. Store that time in DB, file or server.
Is there any server component to this at all? You could use setInterval to call something serverside on a regular basis via ajax, then pull back a date object and once it's finally in the past you could trigger your "alarm"
Related
I'm writing an application in Node.js that needs to schedule functions to be run at specific times. Hours or sometimes days in the future. Currently, I'm doing so with something similar to this:
const now = Date.now();
const later = getSomeFutureTimestamp();
setTimeout(function() {
// do something
}, later - now);
I'm wondering if setTimeout is the proper tool for this job or if there is a tool more suited for long intervals of time. One thing to note is I don't need great precision; if the job runs within a few minutes of the scheduled time, everything should still be fine.
setTimeout should be fine. It's only really delayed if there's blocking code running at the moment when it's meant to execute. So setTimeout is typically 20 milliseconds late. But since your margin is minutes, I don't think it'll be an issue.
However, I'd suggest storing the timestamp at which things should trigger, and just periodically check. That way you only have 1 timer running at any given time.
You also get to keep your timestamps as absolute timestamps - not as relative, "milliseconds in the future" values. That also lets you store them between server restarts, which you can't do as easily with relative times. With your code, the only record of a job being queued is that there's a timer running. If that timer disappears for any reason, you lose all record of a job having been scheduled.
Something like:
function checkForScheduledJobs() {
var now = Date.now(),
job;
// assuming here that the jobs array is sorted earliest to latest
while(jobs.length && jobs[0].timestamp < now) {
jobs.shift().callback();
}
setTimeout(checkForScheduledJobs, 60000); // check each minute
}
You just need to kick it off once. This could be done in an addScheduledJob function (which would also sort the jobs array after adding something to it, etc.)
I am developing a stopwatch application using Javascript/jQuery. The problem is that the milliseconds value is out of sync with REAL milliseconds. I am using function setInterval() with the interval of 1 millisecond, still it is causing this problem.
jsFiddle: http://jsfiddle.net/FLv3s/
Please help!
Use setInterval to trigger updates, but use the system time (via new Date()) for the actual time calculations.
To be honest, I tried nearly the same thing as you do now (Creating an accurate Metronome in Javascript only) - to make a long story short: To be absolutely accurate in terms of milliseconds (or lower) is sadly not (yet) possible with javascript only.
For more insight i recommend this question: Does JavaScript provide a high resolution timer?
or to be more precise this blog article: http://ejohn.org/blog/how-javascript-timers-work/
Best regards,
Dominik
Program execution in any language, not just JavaScript, is not realtime. It will take a tiny amount of time to actually run the code to increment your counter and update the view, and that throws the "timing" off.
Additionally, many browsers have a "minimum timeout" length, which varies between 4 and about 16 (the latter being the computer's own clock timer), which will really mess with your code.
Instead, you should use delta timing.
var startTime = new Date().getTime();
setInterval(function() {
var elapsed = new Date().getTime()-startTime;
// update view according to elapsed time
},25);
If you're worried about it looking choppy, consider using requestAnimationFrame instead, to update the timer exactly once per frame - this has the added benefit of not updating when the user switches tabs (but it will still be timing them) because if the tab is not active then there's no need to redraw stuff.
You can use the new performance object to get a more accurate time. Combine this with requestAnimationFrame instead of setInterval:
var startTime = performance.now(),
currentTime,
isRunning = true;
loop();
function loop(timeElapsed) {
currentTime = performance.now();
if (isRunning) requestAnimationFrame(loop);
}
Just subtract startTime from currentTime.
I left timeElapsed which contains time elapsed handed by rAF which you can may use also for something (or just ignore it).
One note though: not all browsers support this yet (and some may use prefix) so for mobile you need to use the standard system time object.
How can I create an update function in javascript/jquery?
An update function is a function that is run at each step in the game, say 60 times a second for example. It is used a lot in game development.
How can I make something like this in jquery?
Probably you need to use setInterval function.
But I would recommend to use requestAnimationFrame instead as it was designed for developing browser games and can perform 60 calls per second as you need.
why jQuery? just call a function with a frequency of 1000/60 msecs, e.g.
setInterval(function() {
...
}, 1000/60)
SetInterval will be useful to you in this instance.
You can use it like this -
var timer = setInterval(callback,delay);
This code will execute a function named callback every delay miliseconds.
To stop the timer, you can use the clearInterval() method.
clearInterval(timer);
As I stated, the intervals are defined in milliseconds so in order for your callback to execute 60 times a second you would need to pass 16 or 17 milliseconds as the delay parameter.
That will partially depend on your rendering method.
If you will be rendering your "game" in (for instance) a <canvas> element, you might want to use requestAnimationFrame (a javascript native function)
For more information see This helpfull article
From my basic understanding, JavaScript audio visualizers are reflecting the music based on the actual sound waves. I would like to build something like a metronome (http://bl.ocks.org/1399233), where I animate some DOM element every x beats.
The way I'm doing this now is I manually figure out the tempo of the song, say it's 120bpm, then I convert that to milliseconds to run a setInterval callback. But that doesn't seem to work because the browser performance causes it to be imprecise. Is there a better way to make sure a callback is executed exactly at the same tempo a song is in?
If not, what are some other strategies to sync JavaScript animations with a song's tempo that's not an audio visualizer?
Update: something like this it looks like? https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1606
I had a similar problem, in that setInterval could not be relied on to "keep time" over a long period. My solution was the snippet below: (in coffee script, compiled js is in the link at the end)
It provides a drop in replacement for setInetrval that will stay very close to keeping time. With it, you can do this:
accurateInterval(1000 * 60 / bpm, callbackFunc);
See my use case and example that syncs visuals with a provided BPM to a youtube video here: http://squeegy.github.com/MandalaTron/?bpm=64&vid=EaAzRm5MfY8&vidt=0.5&fullscreen=1
accurateInterval code:
# Accurate Interval, guaranteed not to drift!
# (Though each call can still be a few milliseconds late)
window.accurateInterval = (time, fn) ->
# This value is the next time the the timer should fire.
nextAt = new Date().getTime() + time
# Allow arguments to be passed in in either order.
if typeof time is 'function'
[fn, time] = [time, fn]
# Create a function that wraps our function to run. This is responsible for
# scheduling the next call and aborting when canceled.
wrapper = ->
nextAt += time
wrapper.timeout = setTimeout wrapper, nextAt - new Date().getTime()
fn()
# Clear the next call when canceled.
wrapper.cancel = -> clearTimeout wrapper.timeout
# Schedule the first call.
setTimeout wrapper, nextAt - new Date().getTime()
# Return the wrapper function so cancel() can later be called on it.
return wrapper
get the coffee script and js here: https://gist.github.com/1d99b3cd81d610ac7351
This post might be relevant:
Is there a more accurate way to create a Javascript timer than setTimeout?
The gist is that you run a function in your setInterval() slightly faster than your tempo, for example, every 100ms. Long example short, you can track whether or not it's time to play a "beat" by checking the value of (new Date()).getMilliseconds() and seeing if the equivalent of one beat in milliseconds has passed instead of relying on the not-so-accurate setTimeout or setInterval functions.
Even with that, music itself, unless generated by a computer, might not have perfect or consistent tempo, so accounting for mistimed beats could be a hurdle for you, which may be why using audio analysis to find where the actual beats are going to happen could be a better route.
Is there anyway to create a variable speed timer in the browser that will give the exact same results for all operating systems and browsers? If I want 140 beats per minute for every user regardless of their computer speed.
I've been using javascript setTimeout() and setInterval() but I think they are dependant on the speed of the computer and the amount of code in the program.
How do I incorporate the system clock into a browser? Or any other ideas?
You'll have to use setTimeout or setInterval in your solution, but it will be inaccurate for the following reasons:
Browsers have a minimum timeout, which is NOT 0ms. The cross-browser minimum is somewhere around 14ms.
Timers are inexact. They represent queuing time, not execution time. If something else is executing when your timer fires, your code gets pushed to a queue to wait, and may not actually execute until much later.
You're probably going to want to use setTimeout along with manual tracking of the current time (using Date) to step your program. For your case, try something like this:
function someAction(delta) {
// ...
}
function beat() {
var currentTime = +new Date;
var delta = currentTime - pastTime;
if (delta > 430) { // 430ms ~ 140bpm
pastTime = currentTime;
someAction();
}
setTimeout(beat, 107); // 4x resolution
}
var pastTime = +new Date;
beat();
This should approximate 140 beats per minute, using a higher resolution to avoid larger delays. This is just a sample though, you'll probably need to work at it more to get it to perform optimally for your application.
Best you can use is setInterval() or try and derive something from Date().
Note that the time won't be exact, I think because of JavaScript's single threaded nature.
The setTimeout() and setInterval() functions are pretty much the best you're going to get. The timeout parameters to these functions are specified in milliseconds, and are not dependent on the overall speed of the computer running the browser.
However, these functions are certainly not hard-real-time functions, and if the browser is off busy doing something else at the time your timeout or interval expires, there might be a slight delay before your callback function is actually called.