Created
July 26, 2017 00:40
-
-
Save grabcode/98c7b030eb49f8ee650465eb1d691d9c to your computer and use it in GitHub Desktop.
Utility function to cope with `interval` executing asynchronous call.
This file contains hidden or 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
/* | |
`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