This question already has answers here:
What is the JavaScript version of sleep()?
(91 answers)
Closed 7 years ago.
All those setTimeout answers here don't work!
I just want to wait a few seconds between two functions, like this:
do_fn1();
wait(5000);
do_fn2();
From phpied.com:
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
I don't think you can. You'll probably have to
do_fn1();
window.setTimeout(do_fn2, 5000);
Two thoughts:
first of all why not wrap up all of the post delay statements into a wrapper function
var postDelayFunc = function(){
dosomething();
dosomethingelse();
onemorething();
}
then in your code pass this function as the parameter to setTimeout.
//your code
dofunc1();
setTimeout(postDelayFunc, 1000);
Alternatively take a look at jQuery deferred: http://msdn.microsoft.com/en-us/scriptjunkie/gg723713, although you will probably end up writing very similar code.
One thing struck me though about your responses to other answers and possibly where the confusion arises. I think you are looking at your function and seeing a single thread you just want to hold up for a while before carrying on.
You should not do this though in javascript as it ties up the entire browser and will annoy the hell out of users. Instead what you are in effect doing when you use setTimeout, is indicating that when the timeout expires another thread will pick up and execute the passed in function.
As soon as the timeout has been set, the executing thread will continue with the next line (which is why you think the timeout isn't working). What you probably need to do, is set the timeout, and put ALL the post-execution steps into the function handed off to the timer as indicated above.
Saying they all don't work without an example is big call because I'm sure they probably do.
How about this,
do_fn1();
setTimeout(do_fn2, 5000);
All those setTimeout answers here don't work!
Of course they do:
function a() {
alert("I'm pretty sure...");
}
function b() {
alert("...that they work just fine.");
}
a();
setTimeout(b, 5000);
Another hack I will probably use, however personally I would not recommend it.
Check out here http://jsfiddle.net/S6Ks8/1/
function parseSleeps(func){
var fdef = func.toString();
var fbody = fdef.match(/\{([\s\S]*)\}/)[1].split(/sleep\(.*?\)\;?/);
var sleeps = fdef.match(/sleep\((.*?)\)/g);
var fargs = fdef.match(/\(([\s\S]*?)\)/)[1];
var fbodyNew = [];
var times = [];
fbodyNew.push(fbody.shift(), '\n');
for(var i = 0; sleeps && i < sleeps.length; i++){
var sec = sleeps[i].match(/\d+/)[0];
times.push(sec);
fbodyNew.push('setTimeout(function(){\n');
fbodyNew.push(fbody.shift(), '\n');
}
while(times.length){
var sec = times.pop();
fbodyNew.push('}, ', sec, ');\n');
}
return new Function(fargs, fbodyNew.join(''));
}
// Your code from here
function a(str1, str2){
alert(str1);
sleep(3000);
alert(str2);
}
var func = parseSleeps(a);
func('here', 'there');
The smartest way would be to have something like
function a() {
// Do stuff
setTimeout(b, 42)
}
function b() {
// Do other stuff delayed
}
Never "block" any Threads in JS - if you think you have to do there is definately a "cleaner" way to do achieve your aim.
Related
I am trying to use setTimeout for a performance test using console.time() and console.timeEnd(). However, setTimeout() isn't delaying the for() loop.
Here is the JS Fiddle:
// Start the timer.
console.time('testFor');
for ( i = 0; i < 5; i++ ) {
setTimeout( console.log('The number is ' + i), 2000 );
}
// End the timer, get the elapsed time.
console.timeEnd('testFor');
How can I make setTimeout() work in my script and why is it not working for me?
Others have already suggested excellent solutions to your problem - I'd like to offer a closer examination of what was happening with your code.
setTimeout doesn't delay the advancement of your code (like sleep does in other languages) but instead defers running another block of code. It's a weird concept that can be hard to understand; consider the following example:
console.time("Main Program");
console.time("Defered Code");
setTimeout(deferedCode, 1000);
console.timeEnd("Main Program");
function deferedCode() {
console.timeEnd("Defered Code");
}
If we look at the console after running this code, we'll see "Main Program" print out almost immediately, and "Defered Code" roughly a second later.
We've asked setTimeout to run the function deferedCode at a time 1000 ms in the future, and then let the rest of the code run.
Notice also that deferedCode is passed to setTimeout without (). We're passing the function itself and not the result of deferedCode to setTimeout so that setTimeout can choose when to run it.
You could do this without a loop, just using recursion:
var i = 0;
var logNumber = function(){
console.log('The number is ' + i);
i++;
if(i < 5){
setTimeout(logNumber, 2000);
}
}
logNumber();
setTimeout is asynchronous. If you want to call a certain piece of code at regular intervals, use the setInterval function.
I think this code is close to what you are trying to do:
// Start the timer.
console.time('testFor');
var i = 0;
var finish = 5;
var t = setInterval(function() {
if (i < finish) {
console.log('The number is ' + i);
i++;
} else {
clearInterval(t);
// End the timer, get the elapsed time.
console.timeEnd('testFor');
}
}, 2000);
function avoidAfterTime() {
var startTime = new Date().getTime();
var interval = setInterval(function () {
if (new Date().getTime() - startTime > 3000) {
clearInterval(interval);
console.log("more than 2 sec")
return;
}
longWorking();
}, 2000);
}
avoidAfterTime();
function longWorking(){
var t;
for (i = 0; i < 1e10; i++) t = i;
console.log(t);
}
Hello. I am very new to JS. But I need to stop running some function (here it is longWorking) which can be executed for few seconds or for so much time. And I want to abort the function in case of it takes too long. I guess I know how to make it using, for example, threads in some other programming language. But I have no idea about making it in JS. I thought in this way (above)... But it doesn't work. Can someone help me?
hmm, I drafted this example. So it's a function that runs every second and if it takes more than 6 seconds it will stop. So basically you can put your work load in the doSomething() function and let it work every second and stop it if it takes too long. Or you can stop it based on a value. It depends on what do you want to do with it. I used the module pattern to isolate the logic and the variables. So you can encapsulate your logic in a module like way.
(function() {
'use strict';
let timing = 0;
const interval = setInterval(doSomething, 1000);
function doSomething() {
timing++;
if (timing > 5) {
clearInterval(interval);
}
console.log('working');
}
})();
Is this something you are looking for?
This question already has answers here:
Sleep in JavaScript - delay between actions
(15 answers)
Closed 9 years ago.
I want to stop execution for 2 seconds.
<html>
<head>
<title> HW 10.12 </title>
<script type="text/javascript">
for (var i = 1; i <= 5; i++) {
document.write(i);
sleep(2); //for the first time loop is excute and sleep for 2 seconds
};
</script>
</head>
<body></body>
</html>
For the first time loop is excute and sleep for 2 seconds. I want to stop execution for two seconds?
Before using this code, please read all comments.
Javascript is single-threaded, so by nature there should not be a sleep function because sleeping will block the thread. setTimeout is a way to get around this by posting an event to the queue to be executed later without blocking the thread. But if you want a true sleep function, you can write something like this:
function sleep(miliseconds) {
var currentTime = new Date().getTime();
while (currentTime + miliseconds >= new Date().getTime()) {
}
}
Note: The above code is NOT recommended.
There's no (safe) way to pause execution. You can, however, do something like this using setTimeout:
function writeNext(i)
{
document.write(i);
if(i == 5)
return;
setTimeout(function()
{
writeNext(i + 1);
}, 2000);
}
writeNext(1);
You can use setTimeout to do this
function myFunction() {
// your code to run after the timeout
}
// stop for sometime if needed
setTimeout(myFunction, 2000);
This Link might be helpful for you.
Every time I've wanted a sleep in the middle of my function, I refactored to use a setTimeout().
There's no way to stop execution of your code as you would do with a procedural language.
You can instead make use of setTimeout and some trickery to get a parametrized timeout:
for (var i = 1; i <= 5; i++) {
var tick = function(i) {
return function() {
console.log(i);
}
};
setTimeout(tick(i), 500 * i);
}
Demo here: http://jsfiddle.net/hW7Ch/
I'm really confused how these work...the timeout does not seem to keep running it calls begin_anim once and then thats it....
So am hoping someone can see where i went wrong and explain how I implement this?
This is my code:
//test data:
//type = 'up';
//div = document.getElementById('theid');
//marginL = -400;
function timeout_begin(type,div,marginL){
setTimeout(begin_anim(type,div,marginL),1000);
}
function begin_anim(type,div,marginL){
if(type == 'up'){
if(marginL >= '-200'){
if(marginL > '-200'){
div.style.marginLeft = '-200px';
}
return false;
}
marginL += 2;
div.style.marginLeft = marginL+'px';
}
return false;
}
Hope you can help!
You're looking for setInterval!
Also, it's probably better to pass an actual function in, and you can hold a reference to the loop so you can stop it running later if you want to:
var animationLoop = setInterval(function () {
begin_anim(type, div, marginL);
}, 1000);
clearInterval(animationLoop); // This would then stop the loop.
First, you want setInterval, not setTimeout
Second, you'll pass a reference to a function, not a call to a function. Something like:
function timeout_begin(type,div,marginL)
{
setTimeout(
function() {
begin_anim(type,div,marginL);
},
1000
);
}
setTimeout is supposed to call the function only once.
if you want to call the method repeatedly use setInterval(function(){}, 1000/*duration*/)
setTimeout is only expected to execute the function once after the given timeout. See the documentation here: http://www.w3schools.com/jsref/met_win_settimeout.asp
You're probably looking for setInterval (http://www.w3schools.com/jsref/met_win_setinterval.asp) which executes the code at the interval you set until clearInterval is called.
function animateGraph() {
var graph;
for(i=0; i<10; i++)
{
var start = new Date();
while((new Date()) - start <= 500) {/*wait*/}
document.getElementById("timeMark").innerHTML = phoneX[i].epoch;
}
}
The loop works. The wait works. But the document.getElement is not showing up until the last item in the array...why?
Using setTimeout will allow the code to run and not lock up the page. This will allow it to run the code and will not effect other elements on the page.
var cnt = 0;
(function animateGraph() {
document.getElementById("timeMark").innerHTML = phoneX[cnt].epoch;
cnt++;
if (cnt<10){
window.setTimeout(animateGraph,500);
}
})();
The while loop, waiting for a datetime, is not a good way to wait - it just blocks execution. It keeps the browser (including UI, and its updating) frozen until the script finishes. After that, the window is repainted according to the DOM.
Use window.setTimeout() instead:
function animateGraph(phoneX) {
var el = document.getElementById("timeMark")
var i = 0;
(function nextStep() {
if (i < phoneX.length )
el.innerHTML = phoneX[i].epoch;
i++;
if (i < phoneX.length )
window.setTimeout(nextStep, 500);
})();
}
Please note that this runs asynchronous, i.e. the function animateGraph will return before all phoneXes are shown.
Use setTimeout instead of a while loop.
https://developer.mozilla.org/en/DOM/window.setTimeout
Also try something like this.
Javascript setTimeout function
The following snippet uses a helper function to create the timers. This helper function accepts a loop counter argument i and calls itself at the end of the timer handler for the next iteration.
function animateGraph() {
var graph;
setTimeMarkDelayed(0);
function setTimeMarkDelayed(i) {
setTimeout(function() {
document.getElementById("timeMark").innerHTML = phoneX[i].epoch;
if (i < 10) {
setTimeMarkDelayed(++i);
}
}, 3000);
}
}
You actually need some sort of helper function, otherwise you'll end up overwriting the value of i in your for loop in every iteration and by the time your timers run out, i will already be 9 and all handlers will act on the last element in phoneX. By passing i as an argument to the helper function, the value is stored in the local scope of that function and won't get overwritten.
Or you could use setInterval like Radu suggested, both approaches will work.