27

Sorry if this question has already been asked here before, I could not find a suitable answer.

I am wanting to create a JavaScript sleep/delay/wait function that I can call anywhere in the script, like jQuery's .delay()

I am not able to use setTimeout, as I have a script that is generated by php, and so am not able to put it into two different functions, with the timeout in the middle. I need to create a function that allows me to do

alert("time started");
sleep(4000);
alert("time up");

I really do not want to use jQuery.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2704237
  • 351
  • 2
  • 4
  • 6
  • 1
    No, you can't do it like that. As simple as that. Use setTimeout or similar solutions. – Denys Séguret Oct 15 '13 at 19:15
  • 1
    possible duplicate of [What do I do if I want a JavaScript version of sleep()?](http://stackoverflow.com/questions/951021/what-do-i-do-if-i-want-a-javascript-version-of-sleep) – Denys Séguret Oct 15 '13 at 19:17
  • There are many identical questions. You found no suitable answer because you didn't accept that JavaScript doesn't work like it works. – Denys Séguret Oct 15 '13 at 19:18
  • Your reason for not being able to use setTimeout doesn't make sense. You can have one function call the other after the setTimeout delay. Show us the code that doesn't work with setTimeout and we may be able to help you. – Hamza Kubba Oct 15 '13 at 19:18
  • Depending on what that "two functions" means, an inline function called by `setTimeout()` could well be acceptable. – Lee Meador Oct 15 '13 at 19:19
  • 1
    setTimeout, whether you like it or not, is the right answer. You need to restructure your page or functions to handle it if you need delays. – Hamza Kubba Oct 15 '13 at 19:20
  • @HamzaKubba my problem is, is that the user generates the code, by typing into a text box, and using "wait NUMBER seconds", to halt the code. I need a way of converting the "wait NUMBER seconds" into javascript code. – user2704237 Oct 15 '13 at 19:24
  • That doesn't change what I said... use `setTimeout(runMeAfterDelay(), NUMBER * 1000);` – Hamza Kubba Oct 15 '13 at 19:28
  • 1
    @user2704237 This reads like you are trying to implement a new higher language which is based upon _JavaScript_. You can't implement something fundamentally counter to how _JavaScript_ works if it is based on it. – Paul S. Oct 15 '13 at 19:28
  • @Paul: in the meantime JavaScript has implemented [await](http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep/39914235#39914235). – Dan Dascalescu Oct 07 '16 at 10:12

6 Answers6

25

Here's a solution using the new async/await syntax.

async function testWait() {
    alert('going to wait for 5 second');
    await wait(5000);
    alert('finally wait is over');
}

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

Note: You can call function wait only in async functions

tagawa
  • 4,561
  • 2
  • 27
  • 34
Anil Agrawal
  • 2,748
  • 1
  • 24
  • 31
  • 1
    Instead of creating a function that calls `resolve()`, you can just replace it with the resolve function itself: replace `() => { resolve(); }` with `resolve` – Coco Liliace Jan 04 '22 at 00:48
17

You cannot just put in a function to pause Javascript unfortunately.

You have to use setTimeout()

Example:

function startTimer () {
    timer.start();
    setTimeout(stopTimer,5000);
}

function stopTimer () {
    timer.stop();
}

EDIT:

For your user generated countdown, it is just as simple.

HTML:

<input type="number" id="delay" min="1" max="5">

JS:

var delayInSeconds = parseInt(delay.value);
var delayInMilliseconds = delayInSeconds*1000;

function startTimer () {
    timer.start();
    setTimeout(stopTimer,delayInMilliseconds);
}

function stopTimer () {
    timer.stop;
}

Now you simply need to add a trigger for startTimer(), such as onchange.

Deep
  • 920
  • 8
  • 22
  • and what is 'timer' supposed to be? I get an Uncaught ReferenceError: timer is not defined – gicalle Feb 11 '15 at 09:54
  • timer.start() and timer.stop() are placeholder functions. Replace them with whatever commands you want – Deep Feb 11 '15 at 11:12
  • Now you can, in [ES2015 + async/await](http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep/39914235#39914235). – Dan Dascalescu Oct 07 '16 at 10:12
10

You will have to use a setTimeout so I see your issue as

I have a script that is generated by PHP, and so am not able to put it into two different functions

What prevents you from generating two functions in your script?

function fizz() {
    var a;
    a = 'buzz';
    // sleep x desired
    a = 'complete';
}

Could be rewritten as

function foo() {
    var a; // variable raised so shared across functions below
    function bar() { // consider this to be start of fizz
        a = 'buzz';
        setTimeout(baz, x); // start wait
    } // code split here for timeout break
    function baz() { // after wait
        a = 'complete';
    } // end of fizz
    bar(); // start it
}

You'll notice that a inside baz starts as buzz when it is invoked and at the end of invocation, a inside foo will be "complete".

Basically, wrap everything in a function, move all variables up into that wrapping function such that the contained functions inherit them. Then, every time you encounter wait NUMBER seconds you echo a setTimeout, end the function and start a new function to pick up where you left off.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Paul S.
  • 64,864
  • 9
  • 122
  • 138
2

The behavior exact to the one specified by you is impossible in JS as implemented in current browsers. Sorry.

Well, you could in theory make a function with a loop where loop's end condition would be based on time, but this would hog your CPU, make browser unresponsive and would be extremely poor design. I refuse to even write an example for this ;)


Update: My answer got -1'd (unfairly), but I guess I could mention that in ES6 (which is not implemented in browsers yet, nor is it enabled in Node.js by default), it will be possible to write a asynchronous code in a synchronous fashion. You would need promises and generators for that.

You can use it today, for instance in Node.js with harmony flags, using Q.spawn(), see this blog post for example (last example there).

kamituel
  • 34,606
  • 6
  • 81
  • 98
  • Yeah, I wonder why my answer got -1'd. I'd love to see the code as written by OP to work in ES5 browsers. When you show it, please -1 me as much as you want. – kamituel Jul 21 '14 at 07:13
  • This is the correct idea. Since this question is a dupe, I left an [answer](http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep/39914235#39914235) based on ES6 on the original question. – Dan Dascalescu Oct 07 '16 at 10:13
1

You can use this -

function sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > milliseconds){
            break;
        }
    }
}
Anthony Raymond
  • 7,434
  • 6
  • 42
  • 59
Tushar
  • 215
  • 1
  • 2
  • 9
0

You could use the following code, it does a recursive call into the function in order to properly wait for the desired time.

function exportar(page,miliseconds,totalpages)
{
    if (page <= totalpages)
    {
        nextpage = page + 1;
        console.log('fnExcelReport('+ page +'); nextpage = '+ nextpage + '; miliseconds = '+ miliseconds + '; totalpages = '+ totalpages );
        fnExcelReport(page);
        setTimeout(function(){
            exportar(nextpage,miliseconds,totalpages);
        },miliseconds);
    };
}
Emi
  • 1