10

I'm trying to mock out a method which takes a long time for testing purposes but can't find a good way to do this in Javascript. Any good approaches besides writing a very long for loop?

Abdullah Jibaly
  • 53,220
  • 42
  • 124
  • 197
  • what wrong with a very long loop? or a loop that checks the time? – Joseph May 10 '12 at 04:36
  • Nothing wrong, just wish I could do something like `sleep(milliseconds)`. It's harder to figure out how big the loop needs to be but nothing trial and error can't fix. – Abdullah Jibaly May 10 '12 at 04:36
  • In Firefox you can use [trampolining](http://tobyho.com/2010/12/10/trampolines-in-javascript-and/ "Trampolines in Javascript and the Quest for Fewer Nested Callbacks") to make asynchronous JavaScript calls synchronous. – Aadit M Shah May 10 '12 at 04:53
  • what about this: http://alexeypetrushin.github.io/synchronize/docs/index.html – Alexander Mills Dec 05 '14 at 08:24
  • I am looking for this so I can replace the alert( ) function without having to rewrite all of our alerts as asynchronous, so the sleep function definitely has a use case. A 100% CPU core loop will not go over well. Async/Await might work with minimal code change, but not every browser supports the async pattern yet. – Brain2000 Nov 02 '18 at 16:32

3 Answers3

12

How about a loop that checks time?

function sleep(milliSeconds){
    var startTime = new Date().getTime();                    // get the current time
    while (new Date().getTime() < startTime + milliSeconds); // hog cpu until time's up
}
Joseph
  • 117,725
  • 30
  • 181
  • 234
5

If you can use the newer await/await syntax:

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

async function example() {
    await sleep(4000);
    return 1;
}

console.log(await example());
Kevin Seifert
  • 3,494
  • 1
  • 18
  • 14
2

You could make a synchronous AJAX call to a server which defers the response by a certain amount of time as requested by your script. Note however that this method won't work in Firefox as it doesn't support synchronous AJAX calls.

Just use this simple function on the client side:

function sleep(microseconds) {
    var request = new XMLHttpRequest;
    request.open("GET", "/sleep.php?time=" + milliseconds);
    request.send();
}

The code for sleep.php on the server side:

usleep(intval($_GET("sleep")));

Now you can create blocking synchronous functions in JavaScript (with the exception of Firefox) as follows:

alert("Hello");
sleep(1000000); // sleep for 1 second
alert("World");
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • This will burn up a socket connection for an extended period of time though. These are limited. Unless you are using node.js (or some asynchronous framework) it may have scaling issues. – Kevin Seifert Jun 05 '18 at 20:23