Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Promise.takeAtLeast
// Creates a new promise that automatically resolves after some timeout:
Promise.delay = function (time) {
return new Promise((resolve, reject) => {
setTimeout(resolve, time)
})
}
// Throttle this promise to resolve no faster than the specified time:
Promise.prototype.takeAtLeast = function (time) {
return new Promise((resolve, reject) => {
Promise.all([this, Promise.delay(time)]).then(([result]) => {
resolve(result)
}, reject)
})
}
// Make sure this doesn't resolve for at least 300ms, useful for things like
// keeping a loading spinner on screen just long enough to not look janky:
axios.post(`/published-products`, payload)
.takeAtLeast(300)
.then(response => {
this.loading = false
// ...
})
.catch(response => {
this.loading = false
// ...
})
@mavame

This comment has been minimized.

Copy link

commented Aug 28, 2017

I wrote something similar. In my case I needed to wait no more than a certain amount of time for my async task to run. And if it hadn't finished in a set amount of time, reject the promise.
https://gist.github.com/mavame/adbad3a22cdcaaff314ab8fafd8efaba

@skollro

This comment has been minimized.

Copy link

commented Feb 6, 2018

Found out that it works more reliable in Firefox if you're using

window.Promise = Promise
window.Promise.prototype.takeAtLeast = ...
@treetrum

This comment has been minimized.

Copy link

commented Sep 9, 2019

You should be able to simplify the takeAtLeast proto function by not creating an additional promise around Promise.all. See below:

Promise.prototype.takeAtLeast = function(time) {
    return Promise.all([this, Promise.delay(time)]).then(([result]) => result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.