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/
Related
Good day
I have a call to the same function 9 times. Unfortunately it looks like it runs so fast that a couple of function dont finish or get called
loadpaymentboxes('1t1', '1h1', p1t1, p1i1);
loadpaymentboxes('1t2', '1h2', p1t2, p1i2);
loadpaymentboxes('1t3', '1h3', p1t3, p1i3);
loadpaymentboxes('2t1', '2h1', p2t1, p2i1);
loadpaymentboxes('2t2', '2h2', p2t2, p2i2);
loadpaymentboxes('2t3', '2h3', p2t3, p2i3);
loadpaymentboxes('3t1', '3h1', p3t1, p3i1);
loadpaymentboxes('3t2', '3h2', p3t2, p3i2);
loadpaymentboxes('3t3', '3h3', p3t3, p3i3);
How do you chain these calls so that only after the the previous call has finished, it is allowed to run it again.
This code will execute the functions after one second
var i = 1;
var timer = setInterval(function() {
if( i >= 9 ) {
clearInterval( timer );
}
//YourFunction();
console.log(i);
i++;
}, 1000/*Change this time in milliseconds to modify the execution time between functions*/);
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);
I have an interval running every 6 seconds on my page; it populates a bunch of data really nicely.
However, there is one piece of data that is only updated from the DB every 30 seconds. So, I want to wait to execute this callback because if it executes beforehand, it wipes everything out.
My code below waits 30 seconds and then checks. What I'd like is the opposite: Check immediately and then wait 30 seconds before checking again.
I feel like my code is cloogy below and there's a much more elegant solution (though I don't think a do/while loop fits the bill). Am I wrong?
counter = 0;
maxCounts = 5;
function callbackForInterval(){
if(counter === maxCounts){
if({data hasn't changed}){
// wipe everything out!!!
}else{
// do some other stuff
}
counter = 0;
}
counter++;
}
Thanks for any helpful hints.
You can use the remainder operator (%).
var counter = 0;
function callbackForInterval)( {
if (counter++ % 5 === 0) {
// This bit only runs every 5 iterations
}
}
That will run the code on the first iteration. To run it only starting with the 5th, change the post-increment to a pre-increment.
Live Example:
var counter = 0;
function callbackForInterval() {
if (counter++ % 5 === 0) {
snippet.log("big tick");
// This bit only runs every 5 iterations
} else {
snippet.log("little tick");
}
}
var timer = setInterval(callbackForInterval, 500);
setTimeout(function() {
snippet.log("done");
clearInterval(timer);
}, 30000);
snippet.log("(stops after 30 seconds)");
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Side note: I added var to the above, because unless you're declaring that counter variable somewhere, your code is falling prey to The Horror of Implicit Globals.
Learning about callbacks and the solution to this problem eludes me.
It should print a number every second counting down until zero. Currently, it logs the numbers from 10 - 0 but all at once and continues in an infinite loop.
Please help me to gain a better understanding of this situation. I have read up on callbacks and have a conceptual understanding but execution is still a bit tricky.
var seconds = 0;
var countDown = function(){
for(var cnt = 10; cnt > 0; cnt--){
setTimeout(function(x){
return function(){
seconds++
console.log(x);
};
}(cnt), seconds * 1000);
}
}
countDown()
The way your code is working now, it executes a for loop with cnt going from 10 to 1. This works. On each iteration, it schedules a new function to be run in seconds * 1000 milliseconds, carefully and properly isolating the value of cnt in x each time. The problem is that seconds is 0, and it will only be changed once a callback executes; but by the time a callback executes, all of them will already have been scheduled for execution. If you need seconds * 1000 to vary while you’re still scheduling them all (while the for loop is still running), you need to change seconds in the loop, rather than inside one of the callbacks.
Read up on IIFEs to see how they work. In this situation, you're creating a closure of the value you want to print. You had the right idea, but your syntax was off.
var seconds = 0;
var countDown = function () {
var cnt = 10;
// simplify your loop
while (cnt--) {
// setTimeout expects a function
// use an IIFE to capture the current value to log
setTimeout((function (x) {
// return the function that setTimeout will execute
return function (){
console.log(x + 1);
};
}(cnt)), (++seconds) * 1000);
}
};
countDown();
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.