PositiveGuy PositiveGuy -4 years ago 127
Javascript Question

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.

Answer Source

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).
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".

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download