PositiveGuy
PositiveGuy

Reputation: 20182

Sleep function not resolving promise passed into it

I came up with the following sleep function that I'm trying to perfect:

const sleep = (promise, milliseconds) => {
  return new Promise(function(resolve, reject) {
    try {
      setTimeout(() => {
        resolve(promise)
      }, milliseconds)
    }
    catch(err) {
      reject(err)
    }
  })
}

Here is an example using it:

let { error, stdout, stderr } = await sleep(exec(`aws s3api head-bucket --bucket pr-${bucketName}`), 2000)

the problem I have is I get the error sometimes(not always): UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Command failed: aws s3api head-bucket --bucket pr-11

I'm not quite sure how to get my sleep function working. I figured I'd just pass in the promise (in this case I'm passing in the promisified exec() call), do a timeout on it, and return it as a new promise after resolved in the timeout.

This actually works for me, it's just giving me that error but it is definitely working as far as my intention to resolve the passed promisified exec() and then returning its results wrapped in a promise again

const sleep = (promise, milliseconds) => {
  return new Promise((resolve) => {
      setTimeout(() => {
        resolve(promise)
      }, milliseconds)
  })
}

Basically I think what my function is doing is just taking in a promise, and then passing it back after x milliseconds..kinda like a handoff in sports :)...give and go

Upvotes: 1

Views: 639

Answers (1)

Michael Lorton
Michael Lorton

Reputation: 44386

Why is promise an argument? This function should create a promise.

And why is there a try-catch? It can't fail.

All you need is this:

const sleep = milliseconds => 
   new Promise(resolve => setTimeout(resolve, milliseconds));

Edit: remember that promises don't take call-backs and you don't have to manually wrap it in a try. You use .then() and .catch() to compose promises. The OP had a promisified exec and he wanted to combine it with sleep. The possibilities are

const cmdPromise = util.promisify(require('child_process').exec)(cmd)
  .then(() => sleep(2000))
  .then(cmdPromise)
  .then(() => console.log('Done'))
  .catch(e => console.log('Error: " + e));

This waits 2 seconds, then runs the command, waits for it to complete, and prints "Done".

Or, you could

cmdPromise
  .then(() => sleep(2000))
  .then(() => console.log('Done'))
  .catch(e => console.log('Error: " + e));

Which waits for the command to execute, then waits two more seconds, and prints "Done".

Or, and my guess is that this is what you want:

Promise.all([ cmdPromise,
              sleep(2000) ])
  .then(() => console.log('Done')
  .catch(e => console.log('Error: " + e));

This waits for both the command to finish and two seconds to elapse (in parallel) before printing "Done".

Upvotes: 3

Related Questions