Skip to content

Instantly share code, notes, and snippets.

@leofavre
Last active January 20, 2019 23:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leofavre/71fcb20bec2c2fb9031b90b79f9647b2 to your computer and use it in GitHub Desktop.
Save leofavre/71fcb20bec2c2fb9031b90b79f9647b2 to your computer and use it in GitHub Desktop.
Delays the chaining of a promise by a specified time in milliseconds.
/**
* Part of [Canivete](http://canivete.leofavre.com/#waitinpromise)
*
* Delays the chaining of a promise by a specified
* time in milliseconds.
*
* The function is curried so as to be used inside
* the `.then()` method, passing along the resolved
* value from the previous promise step to the next.
*
* Note that if a non-numeric parameter is passed,
* the promise resolves without delay, skipping the
* internal `setTimeout()`.
*
* @category Promise
*
* @param {number} delay The delay in milliseconds.
* @return {Promise} When fulfilled, returns the resolved value from the previous step.
* @public
*
* @example
* Promise.resolve("waiting")
* .then(waitInPromise(1000))
* .then(doSomethingAfterOneSecond);
*/
const waitInPromise = delay => arg =>
(Number.isFinite(delay) && delay > 0) ?
new Promise(resolve => setTimeout(() => resolve(arg), delay)) :
Promise.resolve(arg);
export default waitInPromise;
@djleonskennedy
Copy link

simplest code with one expression:

const waitInPromise = delay => arg =>
  Number.isFinite(delay) && delay > 0
    ? new Promise(resolve => setTimeout(() => resolve(arg), delay))
    : Promise.resolve(arg);

@leofavre
Copy link
Author

@djleonskennedy You are right, I'm updating the code to remove unnecessary returns and curly braces.

@David263
Copy link

David263 commented Jan 20, 2019

Seems to have exactly the same effect as writing a then() containing an explicit ordinary Promise-converted setTimeout, except that the timeout duration is tested to be sure it is reasonable, in case such a check is needed. Myself, I'd rather have the delay written explicitly, since I would not use this functionality often.

Side comment: A perhaps rare use case for such an explicit delay is in browser notification modal boxes: Firefox creates them asynchronously and returns a Promise (using the browser.notifications.create function), but resolves the Promise too early, so multiple notifications created too quickly misbehave. An explicit delay of 500 msec in a surrounding Promise or in a then() works well to give enough time to allow the box to be displayed; an additional overlapping or sequential 2000 msec delay can also be written if you would like the notification box to disappear automatically instead of waiting for the user to click the box to dismiss it. The result is perfect behavior for multiple notification boxes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment