Skip to content

Instantly share code, notes, and snippets.

@eschwartz
Last active January 9, 2017 17:22
Show Gist options
  • Save eschwartz/aa57156e301b022c4b696f00423eeb22 to your computer and use it in GitHub Desktop.
Save eschwartz/aa57156e301b022c4b696f00423eeb22 to your computer and use it in GitHub Desktop.
Poll
/**
* eg.
*
* poll(
* () => Promise.resolve(Math.random()),
* val => val > 0.5
* )
* .then(val => console.log(`You won, with ${val}!`));
*
* @param {():Promise<T>} run
* @param {(v:T):Promise<Bool>} predicate
* @param {{
* timeout: int,
* interval: int
* }} opts
*
* @return {Promise<T>}
*/
function poll(run, predicate, opts) {
predicate || (predicate = val => !!val);
opts = Object.assign({
timeout: 10000,
interval: 100
}, opts);
return new Promise((resolve, reject) => {
const intervalRef = setInterval(() => {
Promise.resolve(run())
.then(val => Promise.resolve(predicate(val))
.then(isComplete => {
if (isComplete) {
clearClock();
resolve(val);
}
})
)
.catch(err => {
clearClock();
reject(err);
})
}, opts.interval);
const timeoutRef = setTimeout(() => {
clearClock();
reject(new Error(`Poll timed out after ${opts.timeout}ms`));
}, opts.timeout || Infinity);
const clearClock = () => {
clearTimeout(timeoutRef);
clearInterval(intervalRef);
};
})
}
/**
* eg.
*
* poll(
* () => Promise.resolve(Math.random()),
* val => val > 0.5
* )
* .then(val => console.log(`You won, with ${val}!`));
*/
function poll<TRes extends any>(
run: () => IMaybePromise<TRes>,
predicate?: (res:TRes) => IMaybePromise<boolean>,
opts?: {
timeout?: number,
interval?: number
}
):
Promise<TRes>
{
predicate || (predicate = val => !!val);
opts = Object.assign({
timeout: 10000,
interval: 100
}, opts || {});
return new Promise((resolve, reject) => {
const intervalRef = setInterval(() => {
Promise.resolve(run())
.then(val => Promise.resolve(predicate(val))
.then(isComplete => {
if (isComplete) {
clearClock();
resolve(val);
}
})
)
.catch(err => {
clearClock();
reject(err);
})
}, opts.interval);
const timeoutRef = setTimeout(() => {
clearClock();
reject(new TimeoutError(`Poll timed out after ${opts.timeout}ms`));
}, opts.timeout || Infinity);
const clearClock = () => {
clearTimeout(timeoutRef);
clearInterval(intervalRef);
};
})
}
type IMaybePromise<TRes extends any> = TRes | Promise<TRes>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment