Last active
November 13, 2018 21:33
-
-
Save tomasswood/62f034d093a34f16a6b62f8292cb97d9 to your computer and use it in GitHub Desktop.
Self looping polling function that waits until each request has finished before it waits before attempting another request. Can also be Cancelled.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sleep timer that can also cancel the request | |
* | |
* @param ms | |
* @param isCancelled | |
* @returns {Promise<any>} | |
*/ | |
const sleep = (ms, isCancelled) => { | |
let timeoutHandler; | |
return new Promise((resolve, reject) => { | |
timeoutHandler = setTimeout(resolve, ms); | |
// When `cancelToken()` is called, we will resolve here and clear the timeout | |
// Then we will reject and prevent any new polling requests from happening | |
isCancelled.then(() => { | |
reject(new Error('Cancelled')); | |
clearTimeout(timeoutHandler); | |
}); | |
}); | |
}; | |
/** | |
* Create a recursive loop that calls a function, waits a set time, and then calls it | |
* again after the timer has finished. Can also be cancelled. | |
* | |
* @param func | |
* @param pollingTime | |
* @param isCancelled | |
* @returns {Promise<any> | Promise<T> | *} | |
*/ | |
export const createPollingRequest = (func, pollingTime, isCancelled) => { | |
return func().finally(async () => { | |
try { | |
await sleep(pollingTime, isCancelled); // Wait this amount of time before executing the next polling request | |
return createPollingRequest(func, pollingTime, isCancelled); | |
} catch (e) { | |
console.error(e); | |
} | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
componentWillUnmount() { | |
this.state.cancelToken(); | |
} | |
// ... | |
/** | |
* Setup polling the data. Ensure we store `cancelToken` somewhere that we can call it later. | |
*/ | |
const setupSubscription = () => { | |
let cancelToken; // This is our cancel token. Call it when we want to cancel a request and stop any future ones | |
const isCancelled = new Promise((resolve) => (cancelToken = resolve)); // Cancelled promise that will resolve when we call `cancelToken()` | |
createPollingRequest(this.loadData, 10000, isCancelled); | |
this.setState({ | |
cancelToken, | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment