Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Utility function to cope with `interval` executing asynchronous call.
/*
`setInterval` triggers a function every X secs.
It's not satifying when you deal with asynchronous functions, such as API calls.
It is indeed possible that the response comes right before the next scheduled call, or even after, defeating the purpose of intervals.
The `interval` function below aims at solving this issue.
Usage:
// real life usage, used in a redux thunk
interval(() => bodymap.get(), {
// condition for early exit
exitIf({ status }) { return status && status !== 'pending' },
// onSuccess handler
onSuccess(payload) {
dispatch(bodymapCreationSucceed(payload));
},
// onError handler
onError(error) {
dispatch(bodymapCreationFailed({
id: payload.id,
error,
}));
},
// onTimeout handler, triggered if `exitIf` hasn't been met after`maxIteration` tries
onTimeout() {
dispatch(failBodymapCreation({
id: payload.id,
error: 'timeout',
}));
},
// number max of iteration - triggers onTimeout handler if maxIteration reached
maxIteration: 12,
// time between 2 iterations (in milliseconds)
time: 5000,
});
*/
export const interval = (fn, props) => {
const { exitIf, onSuccess, onError, onTimeout, maxIteration, time } = props;
let intervalHandler = setTimeout(function () {
return fn()
.then(payload => {
const isExiting = exitIf(payload);
if (isExiting) {
return onSuccess(payload);
}
if (maxIteration > 1) {
intervalHandler = interval(fn, { ...props, maxIteration: maxIteration - 1 });
return intervalHandler;
}
return onTimeout();
})
.catch(error => onError(error));
}, time);
return intervalHandler;
};
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.