Skip to content

Instantly share code, notes, and snippets.

@grabcode
Created July 26, 2017 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grabcode/98c7b030eb49f8ee650465eb1d691d9c to your computer and use it in GitHub Desktop.
Save grabcode/98c7b030eb49f8ee650465eb1d691d9c to your computer and use it in GitHub Desktop.
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