4

I know there is an Answer for this But!! All The Answers covered with only one setTimeout in the loop this Question Looks relevant to me How do I add a delay in a JavaScript loop? But in my Scenario I Have two setTimeout in the Script, How can this be implemented correctly with timing !! The Program works correctly but the timing what I want is not correct !!!

function clickDate(i)
{
  setTimeout((function(){
  alert("4");
  })(),2000);
}
function clickButton(i)
{
  setTimeout((function(){
  alert("5");
})(),4000);
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}
3
  • 2
    Look very closely at the syntax you're using for the callbacks. It is not the same as that used in the post you link to. Commented Jul 20, 2017 at 12:23
  • 2
    don't use (function(){ alert("5"); })(), being an immediately executed function, it will be executed as soon as the code reaches it, and passes the result as a callback. use function(){ alert("5"); } Commented Jul 20, 2017 at 12:24
  • 1
    Okay I'm using callback function to out the the alerts in order 4 5 4 5 4 5 4 5 4 5 but without using callback function I'm getting 4 4 4 4 and then 5 5 5 5. Commented Jul 20, 2017 at 12:40

5 Answers 5

8

You're immediately calling the function when you pass it to setTImeout. Remove the extra parenthesis.

function clickDate(i)
{
  setTimeout(function(){
  alert("4");
  },2000);
}
function clickButton(i)
{
  setTimeout(function(){
  alert("5");
},4000);
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

EDIT

It's a little unclear what exactly it is you want your code to do seeing as you're passing i into your function I assume you want to use it somehow. Currently you're creating timeouts that will all launch at once. You'll need to stagger the delay times if you want them to launch in sequence. The code below logs a "4" every 2 seconds and a "5" every "4" seconds by multiplying the delay time by i+1.

// Currently this code displays a 4 every 2 seconds and a 5 every 4 seconds
function clickDate(i)
{
  setTimeout(function(){
  console.log("4");
  },2000 * (i+1));
}
function clickButton(i)
{
  setTimeout(function(){
  console.log("5");
},4000 * (i+1));
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

Sign up to request clarification or add additional context in comments.

6 Comments

This will also have timing problem.
Your Answers Solves the Timing Problem but the alerts are not in sync !! the out put is 4 4 4 4 and then 5 5 5 5 .
OP wasn't clear about what he wanted the code to do so I tried not to assume too much. However using alert is a bad idea because it won't give you a good idea about how the timing actually works out. Furthermore your for loop will create a bunch of timeouts basically all at once.and probably not at intervals like you're expecting. (For ease I would just multiply the timeout time by i+1).
Okay if I use other than Alerts, let's say a "Click" Event will it be in Sync.
Just use console.log and open up the developer's console. (ctrl+shift+i on Chrome). It'll be much easier to see when the messages come in and in what order without having to click the alert away each time.
|
2

Hello I think you havent read documentation about javascript. It's asynchronous and it will not wait for the event and continue the process. I will give the answer but I highly recommend to read about Javascript it's good for you only here you will get timing problem because your both the function will be called at the same time. Let me give you the example.

function clickDate(i,callback)
{
  setTimeout(function(){
  alert("4");
  callback();//this will call anonymous function in doEverything
  },2000);
}
function clickButton(i)
{
  setTimeout(function(){
  alert("5");
},4000);
}

function doEverything(i)
{
  console.log("In loop index is " , i);
  clickDate(i,function(){
       clickButton(i);
  });
  //look closely here I have passed the function in changeData and will call that funtion from clickDate
  console.log("In loop terminating index is " , i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

So here console log will make you clear about asynchronous functionality. You will see that for loop terminates as it continues it's work and easily completed in 2 seconds so before your first alert for loop will complete it's iteration.

Hopefully this will help.

Comments

1
function functionName() {
    setTimeout(function(){ //Your Code }, 3000);
}

Try this one.

Comments

0

you are calling the callback immediately by adding () to the end of function .

you need to pass the callback with timeout and it will be call for you

setTimeout(function(){
alert('hello');
} , 3000);

2 Comments

what you want to execute exactly in setTimeout
Ya I want setTimeout but i want two setTimeout and in sync and in correct Timing one after the other.
0

Your approach to mocking asynchronous behavior in JavaScript with setTimeout is a relatively common practice. However, providing each function with its own invocation of setTimeout is an anti-pattern that is working against you simply due to the asynchronous nature of JavaScript itself. setTimeout may seem like it's forcing JS to behave in a synchronous way, thus producing the 4 4 4 4 then 5 5 you are seeing on alert with iteration of the for loop. In reality, JS is still behaving asynchronously, but because you've invoked multiple setTimeout instances with callbacks that are defined as anonymous functions and scoped within their own respective function as an enclosure; you are encapsulating control of JS async behavior away from yourself which is forcing the setTimeout's to run in a strictly synchronous manner. As an alternative approach to dealing with callback's when using setTimeout, first create a method that provides the timing delay you want to occur. Example:

// timer gives us an empty named "placeholder" we can use later
// to reference the setTimeout instance. This is important because
// remember, JS is async. As such, setTimeout can still have methods
// conditionally set to work against it.

let timer 

// "delayHandler", defined below, is a function expression which when
// invoked, sets the setTimeout function to the empty "timer" variable
// we defined previously. Setting the callback function as the function 
// expression used to encapsulate setTimeout provides extendable control
// for us later on however we may need it. The "n" argument isn't necessary,
// but does provide a nice way in which to set the delay time programmatically
// rather than hard-coding the delay in ms directly in the setTimeout function
// itself.

const delayHandler = n => timer = setTimeout(delayHandler, n)

Then, define the methods intended as handlers for events. As a side-note, to help keep your JS code from getting messy quickly, wrap your event handler methods within one primary parent function. One (old school) way to do this would be to utilize the JS Revealing Module Pattern. Example:

const ParentFunc = step => {

  // "Private" function expression for click button event handler.
  // Takes only one argument, "step", a.k.a the index
  // value provided later in our for loop. Since we want "clickButton"
  // to act as the callback to "clickDate", we add the "delayHandler"
  // method we created previously in this function expression.
  // Doing so ensures that during the for loop, "clickDate" is invoked
  // when after, internally, the "clickButton" method is fired as a
  // callback. This process of "Bubbling" up from our callback to the parent
  // function ensures the desired timing invocation of our "delayHandler"
  // method. It's important to note that even though we are getting lost
  // in a bit of "callback hell" here, because we globally referenced 
  // "delayHandler" to the empty "timer" variable we still have control
  // over its conditional async behavior.

  const clickButton = step => {
    console.log(step)
    delayHandler(8000)
  }

  // "Private" function expression for click date event handler
  // that takes two arguments. The first is "step", a.k.a the index
  // value provided later in our for loop. The second is "cb", a.k.a
  // a reference to the function expression we defined above as the
  // button click event handler method.

  const clickDate = (step, cb) => {
    console.log(step)
    cb(delayHandler(8000))
  }

  // Return our "Private" methods as the default public return value
  // of "ParentFunc"

  return clickDate(step, clickButton(step))
}

Finally, create the for loop. Within the loop, invoke "ParentFunc". This starts the setTimeout instance and will run each time the loop is run. Example:

 for(let i = 0; i < 4; i++) {

   // Within the for loop, wrap "ParentFunc" in the conditional logic desired
   // to stop the setTimeOut function from running further. i.e. if "i" is 
   // greater than or equal to 2. The time in ms the setTimeOut was set to run
   // for will no longer hold true so long as the conditional we want defined
   // ever returns true. To stop the setTimeOut method correctly, use the 
   // "clearTimeout" method; passing in "timer", a.k.a our variable reference 
   // to the setTimeOut instance, as the single argument needed to do so.   
   // Thus utilizing JavaScript's inherit async behavior in a "pseudo" 
   // synchronous way.

   if(i >= 2) clearTimeout(timer)
   ParentFunc(i)
 }

As a final note, though instantiating setTimeOut is common practice in mocking asynchronous behavior, when dealing with initial invocation/execution and all subsequent lifecycle timing of the methods intended to act as the event handlers, defer to utilizing Promises. Using Promises to resolve your event handlers ensures the timing of method(s) execution is relative to the scenario in which they are invoked and is not restricted to the rigid timing behavior defined in something like the "setTimeOut" approach.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.