export class TimeoutError extends Error {}
/**
* @param {Function} pollFunction - function that should return a promise
* @param {Function} predicate - function to check whether race condition was met during polling
* @param {number} timeout - optional timeout or infinite polling
* @param {number} interval
*
* @example
*
* pollApi(
* () => Promise.resolve(true), // pollFunction
* response => !!response, // predicate
* ).then(console.log); // `true`
*
*/
export const pollApi = (pollFunction, predicate, interval = 150, timeout = null) => {
const checkCondition = (resolve, reject) => {
let pollTimeout = null;
let timeoutTimeout = null;
const pollHandler = () =>
pollFunction().then(response => {
// If the condition is met, we're done!
if (predicate(response)) {
clearTimeout(timeout ? timeoutTimeout : pollTimeout);
resolve(response);
return;
}
pollTimeout = setTimeout(pollHandler, interval);
});
// If the promise has not been resolved within the timeout reject it
if (timeout) {
timeoutTimeout = setTimeout(() => {
clearTimeout(pollTimeout);
reject(new TimeoutError());
}, timeout);
}
// Start first poll
pollHandler();
};
return new Promise(checkCondition);
};