72

I have the following scenario:

setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");

I need the code after the setTimeout to be executed after the code in the setTimeout is executed. Since the code that comes after the setTimeout is not code of my own I can't put it in the function called in the setTimeout...

Is there any way around this?

1

11 Answers 11

66

Is the code contained in a function?

function test() {
    setTimeout(...);     

    // code that you cannot modify?
}

In that case, you could prevent the function from further execution, and then run it again:

function test(flag) {

    if(!flag) {

        setTimeout(function() {

           alert();
           test(true);

        }, 5000);

        return;

    }

    // code that you cannot modify

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

4 Comments

this is great!! but mine is a completely similar case except for there's lot of framework code that sits above the setTimeout call as well, and it can't be made to run again... and it won't be possible to split my code into different functions from the point where setTimeout kicks in.
@David Hedlund : This is nice approach but is there any way to make the code synchronous when the code is not in a function?
I just create a small library gitlab.com/ghit/syncjs to create pseudo synchronous javascript execution.
I wonder what is happening in the background? setTimeOut is meant to 'schedule' a function for later execution, it would be more logic to have setTimeout pushing the function as a callback to the event loop queue ...
48

I came in a situation where I needed a similar functionality last week and it made me think of this post. Basically I think the "Busy Waiting" to which @AndreKR refers, would be a suitable solution in a lot of situations. Below is the code I used to hog up the browser and force a wait condition.

function pause(milliseconds) {
	var dt = new Date();
	while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}

document.write("first statement");
alert("first statement");

pause(3000);

document.write("<br />3 seconds");
alert("paused for 3 seconds");

Keep in mind that this code acutally holds up your browser. Hope it helps anyone.

2 Comments

Actually, this doesn't pause the script execution, but the next script (after call pause function) will be executed after the looping done. Tricky, but functionally it meets the need of the question.
what differentiates this from infinite while loop? because if I run infinite while loop, page crashes, but as long as condition isn't satisfied, isn't this just a loop checking time millions of times? what stops it from crashing and is it efficient for longer intervals?
34

Using ES6 & promises & async you can achieve running things synchronously.

So what is the code doing?

// 1. Calls setTimeout 1st inside of demo then put it into the webApi Stack
// 2. Creates a promise from the sleep function using setTimeout, then resolves after the timeout has been completed;
// 3. By then, the first setTimeout will reach its timer and execute from webApi stack. 
// 4. Then following, the remaining alert will show up.


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

async function demo() {
  setTimeout("alert('this alert is timedout and should be the first');", 5000);
  await sleep(5000);
  alert('this should be the second one');
}
demo();

4 Comments

Outstanding answer! Everyone should do this when possible.
Hope you don't need IE support, it doesn't do async functions.
Perfect. Simple and easy to understand.
@Chris what is this IE you speak of 🤷‍♂️?
7

Just put it inside the callback:

setTimeout(function() {
    alert('this alert is timedout and should be the first');
    alert('this should be the second one');
}, 5000);

4 Comments

But he doesn't have access to the code that fires the setTimeout?
And since the code that comes after the setTimeout is not code of my own I can't put it in the function called in the setTimeout... I am working with a framework, so I can't just put the frameworks code in there...
Sorry for misreading. Well then you are out of luck. setTimeout if always asynchronous.
Dude, this is asynchronous.
6

No, as there is no delay function in Javascript, there is no way to do this other than busy waiting (which would lock up the browser).

3 Comments

Can you please elaborate the busy waiting Idea and its working.
var until = new Date().getTime() + 3000; while(new Date().getTime() < until) {}; alert('3 seconds passed');
I always avoid while for checking without any throttling
4

You can create a promise and await for its fulfillment

const timeOut = (secs) => new Promise((res) => setTimeout(res, secs * 1000));

await timeOut(1000)

Comments

3

ES6 (busy waiting)

const delay = (ms) => {
  const startPoint = new Date().getTime()
  while (new Date().getTime() - startPoint <= ms) {/* wait */}
}

usage:

delay(1000)

1 Comment

doesn't help in loop
2

Here's a good way to make synchronous delay in your code:

async function yourFunction() {
  //your code
  await delay(n);
  //your code
}

function delay(n) {
  n = n || 2000;
  return new Promise(done => {
    setTimeout(() => {
      done();
    }, n);
  });
}

Found it here Right way of delaying execution synchronously in JavaScript without using Loops or Timeouts!

Comments

1
setTimeout(function() {
  yourCode();    // alert('this alert is timedout and should be the first');
  otherCode();   // alert("this should be the second one");
}, 5000);

Comments

1

I think you have to make a promise and then use a .then() so that you can chain your code together. you should look at this article https://developers.google.com/web/fundamentals/primers/promises

Comments

0

You could attempt to replace window.setTimeout with your own function, like so

window.setTimeout = function(func, timeout) {
    func();
}

Which may or may not work properly at all. Besides this, your only option would be to change the original code (which you said you couldn't do)

Bear in mind, changing native functions like this is not exactly a very optimal 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.