Search code examples
javascriptpromisesleepchaining

Implementing a verbose sleep function using a chain of Promises


I am trying to implement a sleep function using Promises in JavaScript.

function sleep(ms) {

  var begin = new Promise(resolve => {
    console.log("Sleep function called for " + ms + " ms\n")
  });

  return new Promise(resolve => setTimeout(resolve, ms))
    .then(() => console.log("Sleep done!" ));

}

and it works. But,

function sleep(ms) {

  var begin = new Promise(resolve => {
    console.log("Sleep function called for " + ms + " ms\n")
  });

  return begin.then(resolve => setTimeout(resolve, ms))
    .then(() => console.log("Sleep done!" ));

}

doesn't, rather it just hangs! What gives?

UPDATE: What I really want to do is write it out as a sequence of promise calls.

function sleep(ms) { 
    var beginAnnounce = new Promise(...);
    var goSleep = new Promise (...);
    var endAnnounce = new Promise...);

    return beginAnnounce.then(goSleep).then(endAnnounce());

}

Solution

  • If you want to compose two promises, you can return the second one in a callback passed to Promise.prototype.then of the first promise.

    Have a look at the following code:

    const sleep = ms => () => new Promise((resolve, reject) => window.setTimeout(resolve, ms));
    
    Promise.resolve()
    .then(() => { console.log('A1');})
    .then(sleep(2000))
    .then(() => {console.log('A2');});
    
    Promise.resolve()
    .then(() => {console.log('B1');})
    .then(sleep(1000))
    .then(() => {console.log('B2');});

    The sleep function is a higher order function which returns another function that returns a promise. This promise is resolved in the call to Window.setTimeout parametrized by the ms passed to sleep.

    As you can see the executions are interleaved and you will see the log output for the statement console.log('B2') of the second promise before the output for console.log('A2'); of the first one.