293

I have this a piece of js in my website to switch images but need a delay when you click the image a second time. The delay should be 1000ms. So you would click the img.jpg then the img_onclick.jpg would appear. You would then click the img_onclick.jpg image there should then be a delay of 1000ms before the img.jpg is shown again.

Here is the code:

jQuery(document).ready(function($) {

    $(".toggle-container").hide();
    $(".trigger").toggle(function () {
        $(this).addClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img_onclick.jpg');
    }, function () {
        $(this).removeClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img.jpg');
    });
    $(".trigger").click(function () {
        $(this).next(".toggle-container").slideToggle();
    });
});
Manoj Sharma
  • 1,467
  • 2
  • 13
  • 20
Blue Orange
  • 2,955
  • 2
  • 14
  • 6
  • 22
    `setTimeout(function(){/*YourCode*/},1000);` – marteljn Jul 26 '13 at 14:15
  • 1
    possible duplicate of [Is there some way to introduce a delay in javascript?](http://stackoverflow.com/questions/24849/is-there-some-way-to-introduce-a-delay-in-javascript) – Lloyd Jul 26 '13 at 14:17
  • possibly looking for `.stop()` though. Have a look here http://api.jquery.com/stop/ – Mark Walters Jul 26 '13 at 14:18
  • Possible duplicate of [Put a Delay in Javascript](https://stackoverflow.com/questions/1183872/put-a-delay-in-javascript) – Anonymous Sep 20 '19 at 20:04

12 Answers12

575

Use setTimeout():

var delayInMilliseconds = 1000; //1 second

setTimeout(function() {
  //your code to be executed after 1 second
}, delayInMilliseconds);

If you want to do it without setTimeout: Refer to this question.

jegtugado
  • 5,081
  • 1
  • 12
  • 35
HIRA THAKUR
  • 17,189
  • 14
  • 56
  • 87
86
setTimeout(function(){


}, 500); 

Place your code inside of the { }

500 = 0.5 seconds

2200 = 2.2 seconds

etc.

maudulus
  • 10,627
  • 10
  • 78
  • 117
79

ES-6 Solution

Below is a sample code which uses aync/await to have an actual delay.

There are many constraints and this may not be useful, but just posting here for fun..

const delay = (delayInms) => {
  return new Promise(resolve => setTimeout(resolve, delayInms));
}

const sample = async () => {
  console.log('a');
  console.log('waiting...')
  let delayres = await delay(3000);
  console.log('b');
}
sample();
Rohith K P
  • 3,233
  • 22
  • 28
  • 6
    It is NOT necessary for `delay` function to be async. This awesome delaying works when a Promise returned by a regular function is awaited in the body of an async function. – Intervoice Sep 11 '19 at 17:28
38

you can use the promise

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

then use this method

console.log("Hello");
sleep(2000).then(() => { console.log("World!"); });

or

console.log("Hello");
await sleep(2000);
console.log("World!");
Amirali Eshghi
  • 963
  • 1
  • 14
  • 21
22

There are two (mostly used) types of timer function in javascript setTimeout and setInterval (other)

Both these methods have same signature. They take a call back function and delay time as parameter.

setTimeout executes only once after the delay whereas setInterval keeps on calling the callback function after every delay milisecs.

both these methods returns an integer identifier that can be used to clear them before the timer expires.

clearTimeout and clearInterval both these methods take an integer identifier returned from above functions setTimeout and setInterval

Example:

setTimeout

alert("before setTimeout");

setTimeout(function(){
        alert("I am setTimeout");
   },1000); //delay is in milliseconds 

  alert("after setTimeout");

If you run the the above code you will see that it alerts before setTimeout and then after setTimeout finally it alerts I am setTimeout after 1sec (1000ms)

What you can notice from the example is that the setTimeout(...) is asynchronous which means it doesn't wait for the timer to get elapsed before going to next statement i.e alert("after setTimeout");

Example:

setInterval

alert("before setInterval"); //called first

 var tid = setInterval(function(){
        //called 5 times each time after one second  
      //before getting cleared by below timeout. 
        alert("I am setInterval");
   },1000); //delay is in milliseconds 

  alert("after setInterval"); //called second

setTimeout(function(){
     clearInterval(tid); //clear above interval after 5 seconds
},5000);

If you run the the above code you will see that it alerts before setInterval and then after setInterval finally it alerts I am setInterval 5 times after 1sec (1000ms) because the setTimeout clear the timer after 5 seconds or else every 1 second you will get alert I am setInterval Infinitely.

How browser internally does that?

I will explain in brief.

To understand that you have to know about event queue in javascript. There is a event queue implemented in browser. Whenever an event get triggered in js, all of these events (like click etc.. ) are added to this queue. When your browser has nothing to execute it takes an event from queue and executes them one by one.

Now, when you call setTimeout or setInterval your callback get registered to an timer in browser and it gets added to the event queue after the given time expires and eventually javascript takes the event from the queue and executes it.

This happens so, because javascript engine are single threaded and they can execute only one thing at a time. So, they cannot execute other javascript and keep track of your timer. That is why these timers are registered with browser (browser are not single threaded) and it can keep track of timer and add an event in the queue after the timer expires.

same happens for setInterval only in this case the event is added to the queue again and again after the specified interval until it gets cleared or browser page refreshed.

Note

The delay parameter you pass to these functions is the minimum delay time to execute the callback. This is because after the timer expires the browser adds the event to the queue to be executed by the javascript engine but the execution of the callback depends upon your events position in the queue and as the engine is single threaded it will execute all the events in the queue one by one.

Hence, your callback may sometime take more than the specified delay time to be called specially when your other code blocks the thread and not giving it time to process what's there in the queue.

And as I mentioned javascript is single thread. So, if you block the thread for long.

Like this code

while(true) { //infinite loop 
}

Your user may get a message saying page not responding.

Nadir Laskar
  • 4,012
  • 2
  • 16
  • 33
12

For sync calls you can use the method below:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
user1188867
  • 3,726
  • 5
  • 43
  • 69
  • for some reason, setTimeOut didn't behave like this one I expect it to be. thanks! – Patrick Tolentino Sep 02 '20 at 14:20
  • calling setTimeout, even with a value of zero, will hand over control to the next item in the javascript event loop, so your code will effectively be paused until it's turn in the js event loop comes around again – david.barkhuizen Aug 19 '21 at 13:33
0

If you need refresh, this is another posibility:

setTimeout(function () { 
    $("#jsSegurosProductos").jsGrid("refresh"); 
}, 1000);
A.A Noman
  • 5,244
  • 9
  • 24
  • 46
oOJITOSo
  • 1
  • 1
0

I'll give my input because it helps me understand what im doing.

To make an auto scrolling slide show that has a 3 second wait I did the following:

var isPlaying = true;

function autoPlay(playing){
   var delayTime = 3000;
   var timeIncrement = 3000;

   if(playing){
        for(var i=0; i<6; i++){//I have 6 images
            setTimeout(nextImage, delayTime);
            delayTime += timeIncrement;
        }
        isPlaying = false;

   }else{
       alert("auto play off");
   }
}

autoPlay(isPlaying);

Remember that when executing setTimeout() like this; it will execute all time out functions as if they where executed at the same time assuming that in setTimeout(nextImage, delayTime);delay time is a static 3000 milliseconds.

What I did to account for this was add an extra 3000 milli/s after each for loop incrementation via delayTime += timeIncrement;.

For those who care here is what my nextImage() looks like:

function nextImage(){
    if(currentImg === 1){//change to img 2
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[1].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[1];
        imgDescription.innerHTML = imgDescText[1];

        currentImg = 2;
    }
    else if(currentImg === 2){//change to img 3
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[2].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[2];
        imgDescription.innerHTML = imgDescText[2];

        currentImg = 3;
    }
    else if(currentImg === 3){//change to img 4
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[3].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[3];
        imgDescription.innerHTML = imgDescText[3];

        currentImg = 4;
    }
    else if(currentImg === 4){//change to img 5
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[4].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[4];
        imgDescription.innerHTML = imgDescText[4];

        currentImg = 5;
    }
    else if(currentImg === 5){//change to img 6
    for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[5].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[5];
        imgDescription.innerHTML = imgDescText[5];

        currentImg = 6;
    }
    else if(currentImg === 6){//change to img 1
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[0].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[0];
        imgDescription.innerHTML = imgDescText[0];

        currentImg = 1;
    }
}
noetix
  • 4,773
  • 3
  • 26
  • 47
0

I'm not an expert in JS domain but I've found a workaround for this problem using setTimeout() and a recursive function as follows:

i=0; //you should set i as a global variable
function recFunc() {
    i++;
    if (i == 1) {
        //do job1
    } else if (i == 2) {
        //do job2
    } else if (i == 3) {
        //do job3
    }
    if (i < 3) { //we have 3 distinct jobs. so the condition is (j < 3)
        setTimeout(function () {
            recFunc();
        }, 2000); //replace 2000 with desired delay
    }
}
//
//
//
recfunc(); //start the process
abc def
  • 19
  • 4
0

True Synchronous JavaScript Delay

None of the above solutions are true JavaScript script delays as they are asynchronous. An asynchronous function or callback script will not pause execution of other functions in the stack but will continue running while the asynchronous function, promise, observable, fetch, or other script starts.

Example: setTimeout() is an asynchronous global function...which means code keeps running after the setTimeout starts. In other words, you will not see a delay in your script from running, only a delay in the execution of the callback function inside the setTimeout.

If you do not want users from interacting with your page or script, you want a blocking synchronous script. Below is a synchronous code set that will block your pages global, single-threaded JavaScript code from running for 1 second, then resume after the delay.

        let datetime1 = new Date().getTime();
        let datetime2 = datetime1+1000;// 1 second delay

        while(datetime1<datetime2) {
            datetime1 = new Date().getTime();
        }
Stokely
  • 12,444
  • 2
  • 35
  • 23
0

Delay helpers with typings:

const wait = (ms: number) => new Promise((res) => setTimeout(res, ms));

/**
 * Run promise with minimum fulfilled time
 */
async function minDelay<T>(promise: () => Promise<T>, ms: number): Promise<T> {
    const [result] = await Promise.all([promise(), wait(ms)]);

    return result;
}

And usage examples:

async function runExamples() {
    console.log('start');

    await wait(1000);

    console.log('after 1 sec sleep');

    const noDelayPromise = () => Promise.resolve(Math.random());
    const result = await minDelay(noDelayPromise, 1000);

    console.log('after 1 sec', result);
}
runExamples();
zemil
  • 3,235
  • 2
  • 24
  • 33
-2

const delay = (delayInms) => new Promise(resolve => setTimeout(resolve, delayInms)); await delay(100)

horiatu
  • 356
  • 2
  • 10