162

Is there a way I can do a sleep in JavaScript before it carries out another action?

Example:

var a = 1 + 3;
// Sleep 3 seconds before the next action here.
var b = a + 4;
BarryCap
  • 326
  • 3
  • 11
Jin Yong
  • 42,698
  • 72
  • 141
  • 187

15 Answers15

161

You can use setTimeout to achieve a similar effect:

var a = 1 + 3;
var b;
setTimeout(function() {
    b = a + 4;
}, (3 * 1000));

This doesn't really 'sleep' JavaScript—it just executes the function passed to setTimeout after a certain duration (specified in milliseconds). Although it is possible to write a sleep function for JavaScript, it's best to use setTimeout if possible as it doesn't freeze everything during the sleep period.

supertopi
  • 3,469
  • 26
  • 38
Steve Harrison
  • 121,227
  • 16
  • 87
  • 72
  • 10
    Also have a look at setInterval(). It's similar to setTimeout(), but your function is called multiple times (until you stop it), which is useful if you want to do something while sleeping (like doing progress updates, keeping some internal state, or whatever). – Anders Sandvig Feb 10 '10 at 08:28
  • 9
    This doesn't answer the question. The question asks for a "sleep" equivalent which this is not. – felwithe Jul 23 '16 at 22:27
  • Though this answer is not match what the question asked, but it's more useful than the loop and compare Date.now(). Nobody what to use a blocked loop the implement sleep. – Li Chunlin Aug 10 '17 at 16:01
  • 2
    Unless, of course, a blocking loop is *exactly* what somebody wants. – Wonko the Sane Oct 05 '18 at 20:01
75

In case you really need a sleep() just to test something. But be aware that it'll crash the browser most of the times while debuggin - probably that's why you need it anyway. In production mode I'll comment out this function.

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

Don't use new Date() in the loop, unless you want to waste memory, processing power, battery and possibly the lifetime of your device.

naktinis
  • 3,957
  • 3
  • 36
  • 52
Rodrigo
  • 4,706
  • 6
  • 51
  • 94
  • 10
    This answer deserves more votes. Starring the question just cause of this answer. – jagc Jan 06 '16 at 08:14
  • what about "too much recursion" warning? – Oki Erie Rinaldi Feb 09 '17 at 04:29
  • 1
    @OkiErieRinaldi There's no recursion there, it's only a loop. – Rodrigo Feb 09 '17 at 13:24
  • 7
    @3.1415926535897932384626433833 Well, somebody asked for a "sleep" function, that's what's here. I used it once, can't remember exactly for what kind of debugging. If I ever need it again, I know exactly where to find it. If you prefer another function, that's your choice. Isn't it great to be able to choose? – Rodrigo May 24 '17 at 01:28
  • 2
    "Busy waiting". – Zeek2 Aug 07 '17 at 08:49
  • @user7892745 I like this answer. E.g. I want to validate if the brower truly stop parsing if I have a long js file in ` – Rick Jul 05 '19 at 09:05
  • 2
    The busy-waiting loop you have been manufacturing does exactly what you hope it won't do: It will use up processing power, battery, and possibly the lifetime of your device. It probably uses memory than `new Date()`, but that might as well depend on the implementation. OK for debugging code, **but** don't even consider to use it in anything halfway productive. – Marcel Waldvogel Jul 22 '20 at 10:43
  • @MarcelWaldvogel Indeed, it may only use less memory. Thank you for correcting me. Also, in the *real* production code, of course this function will be erased and not just commented out. – Rodrigo Apr 06 '21 at 07:34
17

ECMAScript 6 version, using generators with yield for "code blocking":

Because the original question was posted seven years ago, I didn't bother answering with the exact code, because it's just way too easy and already answered. This should help in more complicated problems, like if you need at least two sleeps, or if you are planning to sequence asynchronous execution. Feel free to modify it to fit your needs.

let sleeptime = 100
function* clock()
{
    let i = 0
    while( i <= 10000 )
    {
        i++
        console.log(i); // actually, just do stuff you wanna do.
        setTimeout(
            ()=>
            {
                clk.next()
            }
            , sleeptime
        )
        yield
    }
}

let clk = clock()
clk.next()

function*

() => arrow function

You can also chain events via Promises:

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


sleep(1000).then(function()
{
    console.log('1')
    sleep(1000).then(function()
    {
        console.log('2')
    })
})

Or much simpler and a less fancy way would be

function sleep(ms, f)
{
    return(
        setTimeout(f, ms)
    )
}


sleep(500, function()
{
    console.log('1')
    sleep(500, function()
    {
        console.log('2')
    })
})
console.log('Event chain launched')

If you're just waiting for some condition to happen you can wait like this

function waitTill(condition, thenDo)
{
    if (eval(condition))
    {
        thenDo()
        return
    }

    setTimeout(
        ()    =>
        {
            waitTill(condition, thenDo)
        }
        ,
        1
    )
}

x=0

waitTill(
    'x>2 || x==1'
    ,
    ()    =>
    {
        console.log("Conditions met!")
    }
)

// Simulating the change
setTimeout(
    () =>
    {
        x = 1
    }
    ,
    1000
)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Íhor Mé
  • 896
  • 9
  • 13
13

2018 Update

The latest Safari, Firefox and Node.js are now also supporting async/await/promises.

Using async/await/Promises:

(As of 1/2017, supported on Chrome, but not on Safari, Internet Explorer, Firefox, Node.js)

'use strict';

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

let myAsyncFunc = async function() {
  console.log('Sleeping');
  await sleep(3000);
  console.log('Done');
}

myAsyncFunc();

2017 Update

JavaScript has evolved since this question was asked and now has generator functions, and the new async/await/Promise is being rolled out. Below there are two solutions, one with generator function that will work on all modern browsers, and another, using the new async/await that is not yet supported everywhere.

Using a generator function:

'use strict';

let myAsync = (g) => (...args) => {
    let f, res = () => f.next(),
        sleep = (ms) => setTimeout(res, ms);
    f = g.apply({sleep}, args); f.next();
};

let myAsyncFunc = myAsync(function*() {
    let {sleep} = this;
    console.log("Sleeping");
    yield sleep(3000);
    console.log("Done");
});

myAsyncFunc();

Pay attention to the fact that both these solutions are asynchronous in nature. This means that the myAsyncFunc (in both cases) will return while sleeping.

It is important to note that this question is different than What is the JavaScript version of sleep()? where the requestor is asking for real sleep (no other code execution on the process) rather than a delay between actions.

niry
  • 3,238
  • 22
  • 34
  • 1
    Best answer so far !! I've spent 30 min searching everywhere to find that.. big thx !!! – TOPKAT Feb 17 '18 at 18:46
  • 1
    I missed this answer while looking for a solution and re-invented the bicycle :D If only I'd see it before it would save me hours!! Upvoted! – sserzant Jan 23 '20 at 12:12
  • `let co = gen => (...args) => { let iter = gen(...args); let resume = () => new Promise((resolve, reject) => { let result = iter.next(); if (result.done) resolve(result.value); else Promise.resolve(result.value).then(resume).then(resolve, reject); }); return resume(); };` would let you do `let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);` using the definition of `sleep()` from your second code block. – Patrick Roberts Apr 02 '20 at 22:57
6

Here's a very simple way to do it that 'feels' like a synchronous sleep/pause, but is legit js async code.

// Create a simple pause function
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve,timeoutMsec))

async function main () {
    console.log('starting');
    // Call with await to pause.  Note that the main function is declared asyc
    await pause(3*1000)
    console.log('done');
}
user2330237
  • 1,629
  • 5
  • 20
  • 39
5

Another way to do it is by using Promise and setTimeout (note that you need to be inside a function and set it as asynchronous with the async keyword) :

async yourAsynchronousFunction () {

    var a = 1+3;

    await new Promise( (resolve) => {
        setTimeout( () => { resolve(); }, 3000);
    }

    var b = a + 4;

}
Ostn
  • 803
  • 1
  • 9
  • 27
4

If you want less clunky functions than setTimeout and setInterval, you can wrap them in functions that just reverse the order of the arguments and give them nice names:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript versions:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

You can then use them nicely with anonymous functions:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

Now it reads easily as "after N milliseconds, ..." (or "every N milliseconds, ...")

1j01
  • 3,714
  • 2
  • 29
  • 30
3

Here's a re-write and a demo of a Promise-based sleep() using call to setTimeout(). It also demos a regular call to setTimeout().

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

console.log("Synchronous call");
sleep(2000)
.then(() => console.log("Asynchronous call"));

Image of its run on Repl.it

function sleep(ms) {
    return new Promise(resolve => setTimeout(() => resolve(), ms))
}
console.log("Synchronous call 1");

sleep(4000)
 .then(() => console.log("Asynchronous call 1"));

sleep(2000)
 .then(() => console.log("Asynchronous call 2"));

console.log("Synchronous call 2");

sleep(3000)
 .then(() => console.log("Asynchronous call 3"));

console.log("Synchronous call 3");

sleep(5000)
 .then(() => console.log("Asynchronous call 4"))
 .then(
   sleep(7000)
    .then(()=>console.log("Asynchronous call 5"))
)

console.log("Synchronous call 4");

setTimeout(() => {console.log("Asynchronous call 6")}, 8000);
console.log("Synchronous call 5");
cssyphus
  • 37,875
  • 18
  • 96
  • 111
Digitaizen
  • 31
  • 3
2

You can use plain javascript, this will call your function/method after 5 seconds:

setTimeout(()=> { your_function(); }, 5000);
The Black Horse
  • 2,328
  • 1
  • 14
  • 21
1

You can use setTimeout to call a callback after a specified amount of time:

setTimeout(() => {
    console.log('Called after 1 second');
}, 1000);

If you want to use setTimeout as a promise, you can do this:

const delay = milliseconds => new Promise(resolve => { setTimeout(resolve, milliseconds); });

await delay(1000);

console.log('Called after 1 second');

Since Node.js 16, this functionality is also built-in:

import {setTimeout as delay} from 'node:timers/promises';

await delay(1000);

console.log('Called after 1 second');

If you want a synchronous delay in Node.js or in the browser outside of the main thread, you can use Atomics.wait:

const delay = milliseconds => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);

await delay(1000);

console.log('Called after 1 second');
Richie Bendall
  • 7,738
  • 4
  • 38
  • 58
  • I love the elegant simplicity of this. And it's ONE LINE. Impressive. I send you a virtual beer of your choice. – B-Money Sep 19 '21 at 19:16
1

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

async function myFunction(){  // Function Must be async.
  console.log("First Console")
  await delayer(2000);    // This Will Stop The Code For 2 Seconds
  console.log("Second Console")
}


myFunction()
1

For what is worth

  isPause = true;
  setTimeout(()=>{isPause=false},2000);
  while (!isPause) {
    // delay for 2 seconds
  }
    
Ka Tech
  • 8,937
  • 14
  • 53
  • 78
0

There are several ways to solve this problem. If we use the setTimeout function, let's get to know it first. This function has three parameters: function or code, delay (in milliseconds) and the parameters. Since the function or code parameter is required, the others are optional. Once you have not entered the delay, it will be set to zero.

For more details about the setTimeout() go to this link.

Simplified version:

var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){ 
    b = a + 4; 
    console.log('b = ' + b);
}, 1000);

output:
a = 4
24       --> Number identifier of the list of active timeouts
b = 8


Using the parameter pass:

var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(myFunction, 1000, a);

function myFunction(a)
{
    var b = a + 4;
    console.log('b = ' + b);
}

output:
a = 4
25       --> Number identifier of the list of active timeouts
b = 8



Browser Support:

Chrome     Firefox     Edge     Safari     Opera
1.0        1.0         4.0      1.0        4.0
Alexandre Neukirchen
  • 2,713
  • 7
  • 26
  • 36
0

This is my model that shows how to "sleep" or "DoEvents" in javascript using a generator function (ES6). Commented code:

<html>
<head>
<script>
  "use strict"; // always
  // Based on post by www-0av-Com https://stackoverflow.com/questions/3143928
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
  var divelt, time0, globaln = 0; // global variables
  var MainGenObj = Main(); // generator object = generator function()
window.onload = function() {
  divelt = document.getElementsByTagName("body")[0]; // for addline()
  addline("typeof Main: " + typeof Main);
  addline("typeof MainDriver: " + typeof MainDriver);
  addline("typeof MainGenObj: " + typeof MainGenObj);
  time0 = new Date().valueOf(); // starting time ms
  MainDriver(); // do all parts of Main()
}
function* Main() { // this is "Main" -- generator function -- code goes here
  // could be loops, or inline, like this:

  addline("Part A, time: " + time() + ", " + ++globaln); // part A
  yield 2000;                    // yield for 2000 ms (like sleep)

  addline("Part B, time: " + time() + ", " +  ++globaln); // part B
  yield 3000;                    // yield for 3000 ms (or like DoEvents)

  addline("Part Z, time: " + time() + ", " +  ++globaln); // part Z (last part)
  addline("End, time: " + time());
}
function MainDriver() { // this does all parts, with delays
  var obj = MainGenObj.next(); // executes the next (or first) part of Main()
  if (obj.done == false) { // if "yield"ed, this will be false
    setTimeout(MainDriver, obj.value); // repeat after delay
  }
}
function time() { // seconds from time0 to 3 decimal places
  var ret = ((new Date().valueOf() - time0)/1000).toString();
  if (ret.indexOf(".") == -1) ret += ".000";
  while (ret.indexOf(".") >= ret.length-3) ret += "0";
  return ret;
}
function addline(what) { // output
  divelt.innerHTML += "<br />\n" + what;
}
</script>
</head>
<body>
<button onclick="alert('I\'m alive!');"> Hit me to see if I'm alive </button>
</body>
</html>
dcromley
  • 1,373
  • 1
  • 8
  • 23
0

I know this question is old, but if someone is searching for this, there's a cleaner way of ACTUALLY sleeping in javascript using promises

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

const run = async () => {
    while(true){
        console.log("yay1")
        await sleep(3000)
        console.log("next action")
    }
}

run()

This will always have a 3 seconds pause between the first log and second log

What happens here is,

  1. Using await the code execution of JavaScript pauses until the promise is resolved.

  2. The promise will be resolved when the resolver gets fired. The resolver will be fired when setTimeout is executed.

  3. setTimeout will be executed after a given duration in milliseconds.

DJ Hemath
  • 632
  • 6
  • 18
Isaac Frank
  • 41
  • 1
  • 5