Last active
July 20, 2017 22:02
-
-
Save oakley808/b06d5d99dc896e916aa98945c6bcd8b6 to your computer and use it in GitHub Desktop.
Redux-saga polling recipe with concurrency and canceling
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
// runs on load | |
export function* main() { | |
const pollingInstance = yield fork(pollingWatcher); | |
// fork other watchers ... | |
// if location changes, kill the watcher(s) | |
yield take(LOCATION_CHANGE); | |
yield cancel(pollingInstance); | |
// cancel other watchers ... | |
} | |
// Listen for every START and fork off saga that will start/stop polling | |
export function* pollingWatcher() { | |
yield fork(takeEvery, START, pollRacer); | |
} | |
export function* pollRacer(raceAction) { | |
const { response, cancelPolling } = yield race({ | |
response: call(pollingSaga, raceAction), | |
cancelPolling: take(action => (action.type.endsWith('CANCEL') && action.payload.data.id === raceAction.payload.data.id)) | |
}); | |
} | |
// try polling every 3 seconds until the server completes or errors out | |
// put success or failure actions | |
export function* pollingSaga(action) { | |
try { | |
const { id } = action.payload.data; | |
let status = 'p'; | |
let pollResponse; | |
while (status !== 'complete') { | |
yield call(delay, 3000); | |
pollResponse = yield call(request, someUrl, id); | |
status = pollResponse.data && pollResponse.data.status; | |
if (status === 'error') throw new Error('Runtime error'); | |
} | |
yield put(pollSuccess(pollResponse.data)); | |
} catch (error) { | |
yield put(pollFailure(error)); | |
} finally { | |
if (yield cancelled()) { | |
console.log('pollingSaga cancelled'); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment