Execute script after specific delay using JavaScript - javascript

Is there any JavaScript method similar to the jQuery delay() or wait() (to delay the execution of a script for a specific amount of time)?

Just to add to what everyone else have said about setTimeout:
If you want to call a function with a parameter in the future, you need to set up some anonymous function calls.
You need to pass the function as an argument for it to be called later. In effect this means without brackets behind the name. The following will call the alert at once, and it will display 'Hello world':
var a = "world";
setTimeout(alert("Hello " + a), 2000);
To fix this you can either put the name of a function (as Flubba has done) or you can use an anonymous function. If you need to pass a parameter, then you have to use an anonymous function.
var a = "world";
setTimeout(function(){alert("Hello " + a)}, 2000);
a = "Stack Overflow";
But if you run that code you will notice that after 2 seconds the popup will say 'Hello Stack Overflow'. This is because the value of the variable a has changed in those two seconds. To get it to say 'Hello world' after two seconds, you need to use the following code snippet:
function callback(a){
return function(){
alert("Hello " + a);
}
}
var a = "world";
setTimeout(callback(a), 2000);
a = "Stack Overflow";
It will wait 2 seconds and then popup 'Hello world'.

There is the following:
setTimeout(function, milliseconds);
function which can be passed the time after which the function will be executed.
See: Window setTimeout() Method.

Just to expand a little... You can execute code directly in the setTimeout call, but as #patrick says, you normally assign a callback function, like this. The time is milliseconds
setTimeout(func, 4000);
function func() {
alert('Do stuff here');
}

If you really want to have a blocking (synchronous) delay function (for whatsoever), why not do something like this:
<script type="text/javascript">
function delay(ms) {
var cur_d = new Date();
var cur_ticks = cur_d.getTime();
var ms_passed = 0;
while(ms_passed < ms) {
var d = new Date(); // Possible memory leak?
var ticks = d.getTime();
ms_passed = ticks - cur_ticks;
// d = null; // Prevent memory leak?
}
}
alert("2 sec delay")
delay(2000);
alert("done ... 500 ms delay")
delay(500);
alert("done");
</script>

You need to use setTimeout and pass it a callback function. The reason you can't use sleep in javascript is because you'd block the entire page from doing anything in the meantime. Not a good plan. Use Javascript's event model and stay happy. Don't fight it!

You can also use window.setInterval() to run some code repeatedly at a regular interval.

To add on the earlier comments, I would like to say the following :
The setTimeout() function in JavaScript does not pause execution of the script per se, but merely tells the compiler to execute the code sometime in the future.
There isn't a function that can actually pause execution built into JavaScript. However, you can write your own function that does something like an unconditional loop till the time is reached by using the Date() function and adding the time interval you need.

If you only need to test a delay you can use this:
function delay(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
And then if you want to delay for 2 second you do:
delay(2000);
Might not be the best for production though. More on that in the comments

why can't you put the code behind a promise? (typed in off the top of my head)
new Promise(function(resolve, reject) {
setTimeout(resolve, 2000);
}).then(function() {
console.log('do whatever you wanted to hold off on');
});

The simple reply is:
setTimeout(
function () {
x = 1;
}, 1000);
The function above waits for 1 second (1000 ms) then sets x to 1.
Obviously this is an example; you can do anything you want inside the anonymous function.

I really liked Maurius' explanation (highest upvoted response) with the three different methods for calling setTimeout.
In my code I want to automatically auto-navigate to the previous page upon completion of an AJAX save event. The completion of the save event has a slight animation in the CSS indicating the save was successful.
In my code I found a difference between the first two examples:
setTimeout(window.history.back(), 3000);
This one does not wait for the timeout--the back() is called almost immediately no matter what number I put in for the delay.
However, changing this to:
setTimeout(function() {window.history.back()}, 3000);
This does exactly what I was hoping.
This is not specific to the back() operation, the same happens with alert(). Basically with the alert() used in the first case, the delay time is ignored. When I dismiss the popup the animation for the CSS continues.
Thus, I would recommend the second or third method he describes even if you are using built in functions and not using arguments.

As other said, setTimeout is your safest bet
But sometimes you cannot separate the logic to a new function then you can use Date.now() to get milliseconds and do the delay yourself....
function delay(milisecondDelay) {
milisecondDelay += Date.now();
while(Date.now() < milisecondDelay){}
}
alert('Ill be back in 5 sec after you click OK....');
delay(5000);
alert('# Im back # date:' +new Date());

delay function:
/**
* delay or pause for some time
* #param {number} t - time (ms)
* #return {Promise<*>}
*/
const delay = async t => new Promise(resolve => setTimeout(resolve, t));
usage inside async function:
await delay(1000);
Or
delay(1000).then(() => {
// your code...
});
Or without a function
new Promise(r => setTimeout(r, 1000)).then(() => {
// your code ...
});
// or
await new Promise(r => setTimeout(r, 1000));
// your code...

I had some ajax commands I wanted to run with a delay in between. Here is a simple example of one way to do that. I am prepared to be ripped to shreds though for my unconventional approach. :)
// Show current seconds and milliseconds
// (I know there are other ways, I was aiming for minimal code
// and fixed width.)
function secs()
{
var s = Date.now() + ""; s = s.substr(s.length - 5);
return s.substr(0, 2) + "." + s.substr(2);
}
// Log we're loading
console.log("Loading: " + secs());
// Create a list of commands to execute
var cmds =
[
function() { console.log("A: " + secs()); },
function() { console.log("B: " + secs()); },
function() { console.log("C: " + secs()); },
function() { console.log("D: " + secs()); },
function() { console.log("E: " + secs()); },
function() { console.log("done: " + secs()); }
];
// Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)
{
setTimeout(cmd, ms * i);
});
// Log we've loaded (probably logged before first command)
console.log("Loaded: " + secs());
You can copy the code block and paste it into a console window and see something like:
Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076

The simplest solution to call your function with delay is:
function executeWithDelay(anotherFunction) {
setTimeout(anotherFunction, delayInMilliseconds);
}

Related

How to make the refresh frequency of setTimeout a variable?

I want a function I am writing to call itself automatically. I want to be able to parse the frequency at which it calls itself via the first time I parse it. It would then use that same value internally with the JS setTimeout() function to call itself repeatedly again at the same frequency.
So you can see what I have in the sample below:
function testFunction(refreshFrequ){
setTimeout(function() {
console.log("frequency: "+refreshFrequ);
testFunction(refreshFrequ);
}, refreshFrequ);
}
// run the 1st time
testFunction(5000);
The problem is that this doesn't work as from the second time it runs onwards the parsed timeout isn't evaluated. The console output gives a clue to what's going on here:
frequency: undefined
How would I get this working, nothing so far has helped.
Try Window setInterval() Method instead. Also see this answer and this answer for more information.
var autoInterval;
var elapsed = 0;
function myStartFunction(refreshFrequ) {
if (!autoInterval) {
autoInterval = setInterval(function() {
elapsed++;
document.getElementById("txt").innerHTML = refreshFrequ * elapsed + " elapsed.";
console.log("frequency interval: " + refreshFrequ + " x " + elapsed);
}, refreshFrequ);
}
}
function myStopFunction() {
if (autoInterval) {
clearInterval(autoInterval);
autoInterval = null;
elapsed = 0;
document.getElementById("txt").innerHTML = "Interval was reset.";
console.log("interval stopped");
}
}
myStartFunction(5000);
<p>The setInterval() method has started automatically.</p>
<button onclick="myStartFunction(1000)" title="Start with 1000 ms interval. Clicking this button while the event is active should not create a new interval instance.">Start</button> <button onclick="myStopFunction()" title="Click to stop and clear the interval instance.">Stop</button>
<p id="txt">0 elapsed.</p>
Edit: Although there was no mention of the potential duplicate function calls, the other answer should be taken into consideration, especially if the event can arbitrarily be executed. The if statement was imposed in order to prevent duplicate events from being stacked up against the original instance; otherwise, each additionally executed function would result in a unique instance, which could then further create unstoppable multiple events, so I must give credit where credit is due. Kudos to Tymek!
You might want to use setInterval instead.
var testFunction = (function () { // This will "build"/"enclose" our function
var handle = null; // ID of the interval
return function (freq) {
if (handle !== null) clearInterval(handle);
handle = setInterval(function() {
console.log("frequency: " + freq);
}, freq);
};
})();
With this if you re-initialize interval, you will not create another instance of it (having 2 functions ticking).
You can learn more about setInterval at: https://www.w3schools.com/jsref/met_win_setinterval.asp
and more about how JavaScript functions works at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Creating a "delay" function in JS?

I've been reading about setTimeout and other such timers. But I'm wondering if it's possible to work up a custom function so that all you would need to do is something like this:
//code
delay(time);
//more code
Is this possible?
UPDATE: Ok, I kind of get it. So if that isn't reasonably possible, how would you go about delaying a loop AFTER the first time. I want it to run immediately upon execution but they delay on each iteration afterward.
New UPDATE: I figure since my initial thought fell through, it might just be easier to show you the code I have.
function autoFarm (clickEvent){
var farmTargets = [
"6_300_1",
"6_300_3",
"6_300_4",
"6_300_5",
"6_300_7"];
setTimeout(function() {
$.each (farmTargets, function(index, target){
var extraData = '{"end_pos":"' + target + '","purpose":0,"upshift":1,"bring_res":{"0":0,"2":0,"1":0},"bring_ship":{"1":25,"11":0},"rate":100,"start_pos":"6_300_2"}';
var finalData = baseDataDora + extraData + "&type=1";
setTimeout(function(){
for (i = 0; i < farmTargets.length; i++){
postRequest(sendFleetURL + getSign(extraData). finalData, function(json){
});
}
}, 15000);
});//End each loop
}, 1320000);
}//End autoFarm
Basically, it should execute immediately and run the for loop 5 times on the first array element 15 seconds apart. Then 22 minutes later move to the next set and repeat for the entire array.
You can achieve something along those lines with generators. The idea is that continuation passing style (callback hell) can be flattened. The generator uses the yield keyword to pause the function, until the callback resumes it by calling its next method:
var async = function(gen) {
var g = gen()
function next(x) {
var cur = g.next(x)
if (cur.done) {
return cur.value
}
cur.value(next)
}
next()
}
var delay = function(time) {
return function(f) {
setTimeout(f, time)
}
}
async(function* () {
console.log('before')
yield delay(1000) // waits one second
console.log('middle')
yield delay(1000) // waits one second
console.log('after')
})
In CPS it would read something like:
console.log('before')
setTimeout(function() {
console.log('middle')
setTimeout(function() {
console.log('after')
}, 1000)
}, 1000)
This works in Chrome, Firefox and iojs today.
This isn't possible because of the way single-threaded event loops work. If this function were to exist, it would cause the entire UI thread to freeze until the delay was satisfied. setTimeout(cb, delay) is the nearest facility which schedules a function to be executed no earlier than the delay and at the end of the current event loop tick.
Update: Before somebody calls me on it, yes, you can theoretically engineer a delay function that freezes everything in place for a set amount of time. However, there is no reasonable excuse to do it this way.
To your second question:
function hello() {
console.log('hello');
}
// execute immediately
hello();
// then every 5 seconds
setInterval(hello, 5000);
As-written, no that's not possible.
If, instead you were to use a queue, delays in that manner are trivial.
jQuery's .queue() and .delay() functions are a good example of how this works, so I will use them as an example, however the general point stands for any queueing library.
Instead of:
//code
delay(time)
//more code
With a queue, you'd write:
$('...') //some selector to act on for jQuery
.queue(function (next) {
//code
//Indicate that the queued call is finished.
next();
//This allows async code to be executed in the queue,
//such as ajax and animations
})
.delay(time)
.queue(function (next) {
//more code
next();
});
Now, even if you ignore the lines used for comments, you can tell that there's a bit more boilerplate to achieve the desired behavior. I don't feel that it's excessive, because I find it relatively easy to read:
queue something to happen
wait for some number of milliseconds
queue something else to happen
Using a Promise, calling it inside an asynchronous function.
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const any_function = async() => {
await delay(2000);
console.log('this log has been delayed 2 secs')
}

Javascript sleep/delay/wait function

Sorry if this question has already been asked here before, I could not find a suitable answer.
I am wanting to create a JavaScript sleep/delay/wait function that I can call anywhere in the script, like jQuery's .delay()
I am not able to use setTimeout, as I have a script that is generated by php, and so am not able to put it into two different functions, with the timeout in the middle. I need to create a function that allows me to do
alert("time started");
sleep(4000);
alert("time up");
I really do not want to use jQuery.
Here's a solution using the new async/await syntax.
async function testWait() {
alert('going to wait for 5 second');
await wait(5000);
alert('finally wait is over');
}
function wait(time) {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}
Note: You can call function wait only in async functions
You cannot just put in a function to pause Javascript unfortunately.
You have to use setTimeout()
Example:
function startTimer () {
timer.start();
setTimeout(stopTimer,5000);
}
function stopTimer () {
timer.stop();
}
EDIT:
For your user generated countdown, it is just as simple.
HTML:
<input type="number" id="delay" min="1" max="5">
JS:
var delayInSeconds = parseInt(delay.value);
var delayInMilliseconds = delayInSeconds*1000;
function startTimer () {
timer.start();
setTimeout(stopTimer,delayInMilliseconds);
}
function stopTimer () {
timer.stop;
}
Now you simply need to add a trigger for startTimer(), such as onchange.
You will have to use a setTimeout so I see your issue as
I have a script that is generated by PHP, and so am not able to put it into two different functions
What prevents you from generating two functions in your script?
function fizz() {
var a;
a = 'buzz';
// sleep x desired
a = 'complete';
}
Could be rewritten as
function foo() {
var a; // variable raised so shared across functions below
function bar() { // consider this to be start of fizz
a = 'buzz';
setTimeout(baz, x); // start wait
} // code split here for timeout break
function baz() { // after wait
a = 'complete';
} // end of fizz
bar(); // start it
}
You'll notice that a inside baz starts as buzz when it is invoked and at the end of invocation, a inside foo will be "complete".
Basically, wrap everything in a function, move all variables up into that wrapping function such that the contained functions inherit them. Then, every time you encounter wait NUMBER seconds you echo a setTimeout, end the function and start a new function to pick up where you left off.
The behavior exact to the one specified by you is impossible in JS as implemented in current browsers. Sorry.
Well, you could in theory make a function with a loop where loop's end condition would be based on time, but this would hog your CPU, make browser unresponsive and would be extremely poor design. I refuse to even write an example for this ;)
Update: My answer got -1'd (unfairly), but I guess I could mention that in ES6 (which is not implemented in browsers yet, nor is it enabled in Node.js by default), it will be possible to write a asynchronous code in a synchronous fashion. You would need promises and generators for that.
You can use it today, for instance in Node.js with harmony flags, using Q.spawn(), see this blog post for example (last example there).
You can use this -
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
You could use the following code, it does a recursive call into the function in order to properly wait for the desired time.
function exportar(page,miliseconds,totalpages)
{
if (page <= totalpages)
{
nextpage = page + 1;
console.log('fnExcelReport('+ page +'); nextpage = '+ nextpage + '; miliseconds = '+ miliseconds + '; totalpages = '+ totalpages );
fnExcelReport(page);
setTimeout(function(){
exportar(nextpage,miliseconds,totalpages);
},miliseconds);
};
}

Synchronous delay in code execution

I have a code which needs to be executed after some delay say 5000 ms.Currently I am using setTimeout but it is asynchronous and i want the execution to wait for its return. I have tried using the following:
function pauseComp(ms)
{
var curr = new Date().getTime();
ms += curr;
while (curr < ms) {
curr = new Date().getTime();
}
}
But the code i want to delay is drawing some objects using raphaeljs and the display is not at all smooth. I am trying to use doTimeout plugin. I need to have a delay only once as the delay and code to be delayed are both in a loop. I have no requirement for a id so I am not using it.
For example:
for(i; i<5; i++){ $.doTimeout(5000,function(){
alert('hi'); return false;}, true);}
This waits for 5 sec befor giving first Hi and then successive loop iterations show alert immediately after the first. What I want it to do is wait 5 sec give alert again wait and then give alert and so on.
Any hints/ suggestions are appreciated!
Variation on the accepted answer which is just as good as this one.
Also, I agree with the caveats of preferring setTimeout and asynchronous function calling but sometimes e.g., when building tests, you just need a synchronous wait command...
function wait(ms) {
var start = Date.now(),
now = start;
while (now - start < ms) {
now = Date.now();
}
}
if you want it in seconds, divide start ms by 1000 on the while check...
=== EDIT ===
I noticed that my answer has bubbled to the top but it really shouldn't be the top answer. That was written as an alternative in case you cannot use async / await in your code or you're waiting for a trivial amount of time (like a second or two for testing).
The top answer should note that the async/await pattern is a much better way of doing this and will significantly use less energy and CPU cycles.
See #michaelolof 's answer below for example....
const wait = (msec) => new Promise((resolve, _) => {
setTimeout(resolve, msec));
});
(async () => {
console.log("Start...")
await wait(5000);
console.log("...End")
})();
If you'd like to take advantage of the new async/await syntax, You can convert set timeout to a promise and then await it.
function wait(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Done waiting");
resolve(ms)
}, ms )
})
}
(async function Main() {
console.log("Starting...")
await wait(5000);
console.log("Ended!")
})();
Synchronous wait (only for testing!):
const syncWait = ms => {
const end = Date.now() + ms
while (Date.now() < end) continue
}
Usage:
console.log('one')
syncWait(5000)
console.log('two')
Asynchronous wait:
const asyncWait = ms => new Promise(resolve => setTimeout(resolve, ms))
Usage:
(async () => {
console.log('one')
await asyncWait(5000)
console.log('two')
})()
Alternative (asynchronous):
const delayedCall = (array, ms) =>
array.forEach((func, index) => setTimeout(func, index * ms))
Usage:
delayedCall([
() => console.log('one'),
() => console.log('two'),
() => console.log('three'),
], 5000)
Using the new Atomics API, you can start synchronous delays without performance spikes:
const sleep = milliseconds => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds)
sleep(5000) // Sleep for 5 seconds
console.log("Executed after 5 seconds!")
JavaScript is a single-threaded language. You cannot combine setTimeout and synchronous processing. What will happen is, the timer will lapse, but then the JS engine will wait to process the results until the current script completes.
If you want synchronous methods, just call the method directly!
If you want to process something after the setTimeout, include it or call it from the timeout function.
Non-timeout loops (that check the time or count to 1000000 or whatever) just lock up the browser. setTimeout (or the $.doTimeout plugin) is the best way to do it.
Creating timeouts within a loop won't work because the loop doesn't wait for the previous timeout to occur before continuing, as you've discovered. Try something more like this:
// Generic function to execute a callback a given number
// of times with a given delay between each execution
function timeoutLoop(fn, reps, delay) {
if (reps > 0)
setTimeout(function() {
fn();
timeoutLoop(fn, reps-1, delay);
}, delay);
}
// pass your function as callback
timeoutLoop(function() { alert("Hi"); },
5,
5000);
(I just cobbled this together quickly, so although I'm confident that it works it could be improved in several ways, e.g., within the "loop" it could pass an index value into the callback function so that your own code knows which iteration it is up to. But hopefully it will get you started.)
I have made a simple synchronous timeout function. It works in two different ways, callback and non-callback.
function:
function wait(ms, cb) {
var waitDateOne = new Date();
while ((new Date()) - waitDateOne <= ms) {
//Nothing
}
if (cb) {
eval(cb);
}
}
callback example:
wait(5000,"doSomething();");
non-callback example:
console.log("Instant!");
wait(5000);
console.log("5 second delay");
JavaScript is single-threaded
It is impossible to make a synchronous delay in javascript, simply because JavaScript is a single-threaded language. The browser (most common JS runtime environment) has what's called the event loop. So everything that the browser does happens in this very loop. And when you execute a script in the browser, what happens is:
The event loop calls your script
Executes it line by line
Once the script has finished*, the event loop continues running
Notice that all of this is happening during a single frame of the event loop! And that means that no other operation (like rendering, checking for user input, etc.) can happen before the script has exited. (*) The exception is async JavaScript, like setTimeout/Interval() or requestAnimationFrame() which are not run on the main thread. So from event loops prespective, the script has finished running.
This implies that if there were a synchronous delay in JavaScript, the whole browser would have to wait for the delay to finish, and meanwhile it's unable to do anything. So there is no, and there won't be any synchronous delay in JS.
Alternative - Maybe?
The alternative depends on the actual thing you want to do. In my case, I have a requestAnimationFrame() loop. So all I needed to do was to store the time, and check between the old time and new time in the loop.
let timer =
{
startTime: 0,
time: 1000, // time for the counter in milliseconds
restart: true // at the beginning, in order to set startTime
};
loop();
function loop()
{
if(timer.restart === true)
{
timer.startTime = Date.now();
timer.restart = false;
}
if((Date.now() - timer.startTime) >= timer.time)
{
timer.restart = true;
console.log('Message is shown every second');
// here put your logic
}
requestAnimationFrame(loop);
}
Here's how you can use the JQuery doTimeout plugin
jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] );
From the docs: "If the callback returns true, the doTimeout loop will execute again, after the delay, creating a polling loop until the callback returns a non-true value."
var start = Date.now();
console.log("start: ", Date.now() - start);
var i = 0;
$.doTimeout('myLoop', 5000, function() {
console.log(i+1, Date.now() - start);
++i;
return i == 5 ? false : true;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-dotimeout/1.0/jquery.ba-dotimeout.min.js"></script>
Node solution
Use fs.existsSync() to delay
const fs = require('fs');
const uuidv4 = require('uuid/v4');
/**
* Tie up execution for at-least the given number of millis. This is not efficient.
* #param millis Min number of millis to wait
*/
function sleepSync(millis) {
if (millis <= 0) return;
const proceedAt = Date.now() + millis;
while (Date.now() < proceedAt) fs.existsSync(uuidv4());
}
fs.existsSync(uuidv4()) is intended to do a few things:
Occupy the thread by generating a uuid and looking for a non-existent file
New uuid each time defeats the file system cache
Looking for a file is likely an optimised operation that should allow other activity to continue (i.e. not pin the CPU)
Inspired by #andrew65952 but more modern-like and faster
function wait(ms) {
const now = Date.now()
while (Date.now() - now <= ms) { /* do nothing */}
}
Solution using function generators. To show that it can be done. Not recommended.
function wait(miliseconds){
const gen = function * (){
const end = Date.now() + miliseconds;
while(Date.now() < end){yield};
return;
}
const iter = gen();
while(iter.next().done === false);
}
console.log("done 0");
wait(1000);
console.log("done 1");
wait(2000);
console.log("done 2");

Javascript functions through the url bar with a delay

So.. I have a webpage with a javascript function I wish to execute..
Not knowing javascript very well I exectue the function through the url bar..
javascript: Myfunct1();
javascript: Myfunct2();
Now what I really need to be able to do is a long sleep, execute the first function, sleep for a little, then execute the second function, then loop forever.. something like:
javascript: while(1) { Sleep(20000); Myfunct1(); Sleep(5000); Myfunct2() };
Obviously there isn't a 'Sleep' function.. and this is my problem.. After looking at various posts about 'setTimeout;, I tried that but have been unable to get it right.. was wondering if somebody would take pitty and a poor javascript simpleton and show me the way to do this?
have a look at setTimeout(). This will give you the delay you're looking for.
http://www.w3schools.com/js/js_timing.asp
Just pop this into your HTML before the </body> tag
<script type="text/javascript"><!--
setTimeout(function(){
Myfunct1();
setTimeout(function(){
Myfunct2();
},5000);
},20000);
--></script>
You can use setInterval in conjuction with setTimeout function:
setTimeout('Myfunct1(); setInterval("Myfunct1();", 25000);', 20000);
setTimeout('Myfunct2(); setInterval("Myfunct2();", 25000);', 25000);
This will accomplish the functionality like in your example without hanging the browser. Basicallly, it will Myfunct1() after 20s, and set it to run again 25s after that. Same thing is with Myfunct2(), except that it first run after 25s.
Here's a function that allows you to call alternating functions, waiting a specified amount of time between each invocation:
function alt(fn1, tm1, fn2, tm2) {
var curr, time;
(function next() {
curr = (curr === fn1) ? fn2 : fn1;
time = (time === tm1) ? tm2 : tm1;
window.setTimeout(function() {
curr();
next();
}, time);
})();
}
Use it like this:
alt(Myfunct1, 20000,
Myfunct2, 5000);
This will wait 20 seconds, then call Myfunct1, then wait 5 seconds and call Myfunct2, then wait 20 seconds and call Myfunct1 again, and so on.
Here's a general purpose version that accepts any number of function/timeout pairs:
function alt() {
var args = arguments;
(function next(i) {
if (i == args.length)
i = 0;
window.setTimeout(function() {
args[i]();
next(i + 2);
}, args[i + 1]);
})(0);
}
It's used the same way, but can accept more than two pairs:
alt(function(){console.log("1")}, 2000,
function(){console.log("2")}, 1000,
function(){console.log("3")}, 5000);
If this were real code there's a lot more you could do, like verify arguments and/or specify default timeouts when not provided for any of the given functions.

Categories

Resources