Blue Orange
Blue Orange

Reputation: 3195

How to set time delay in javascript

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();
    });
});

Upvotes: 317

Views: 1529455

Answers (6)

Rohith K P
Rohith K P

Reputation: 3551

Below is sample code which uses ES6’s async/await to resume execution of a function after a delay.

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();

Upvotes: 103

Stokely
Stokely

Reputation: 15769

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();
        }

Upvotes: 2

abc def
abc def

Reputation: 61

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

Upvotes: 1

user1188867
user1188867

Reputation: 3978

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;
    }
  }
}

Upvotes: 10

HIRA THAKUR
HIRA THAKUR

Reputation: 17757

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.

Upvotes: 610

Nadir Laskar
Nadir Laskar

Reputation: 4150

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.

Upvotes: 24

Related Questions