Last active
December 6, 2019 20:47
-
-
Save oshikryu/9cc853b5f4cdfdca3f6348c996bf9bec to your computer and use it in GitHub Desktop.
polling-endpoint-saga
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
import * as types from './types'; | |
export const watchPollEndpoint = () => { | |
return { | |
types: types.WATCH_POLL_ENDPOINT, | |
} | |
} | |
export const stopPolling = () => { | |
return { | |
types: types.STOP_POLLING, | |
} | |
} | |
export const setItems = (items) => { | |
return { | |
types: types.SET_ITEMS, | |
items, | |
} | |
} |
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
export default const pollReducer(state={}, action) { | |
switch (action.type) { | |
case SET_ITEMS: | |
return { | |
items: action.items | |
} | |
default: | |
return state | |
} | |
} |
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
import { put, call, fork, takeLatest, cancel } from 'redux-saga/effects'; | |
import * as actions from './actions'; | |
import * as types from './types'; | |
const POLLING_DELAY = 3000; | |
/** | |
* Explicitly cancelling a provided task | |
* | |
* @param {Task} pollTask | |
* @method *cancelPolling | |
*/ | |
export function *cancelPolling(pollTask) { | |
yield cancel(pollTask); | |
} | |
/** | |
* This method makes an API call to an endpoint within a try/catch and stops polling if the | |
* endpoint returns in an error state. | |
* | |
* Cancelling polling ensures that repeated bad calls (404/500) won't continue to hammer the server | |
* | |
* @method *pollAPICall | |
*/ | |
export function *pollAPICall() { | |
try { | |
const res = yield call('/my-poll-endpoint'); | |
yield put(actions.setItems(res)); | |
} catch (e) { | |
console.error(e); | |
yield put(actions.stopPolling()); | |
} | |
} | |
/** | |
* This method sets up a continuous loop to make an API request with a delay after the API call | |
* returns | |
* | |
* @method *pollEndpointLoop | |
* | |
*/ | |
export function *pollEndpointLoop() { | |
while (true) { | |
try { | |
yield fork(pollAPICall); | |
// optional delay | |
yield call(delay, POLLING_DELAY); | |
} catch(e) { | |
console.error(e); | |
} | |
} | |
} | |
/** | |
* This method initializes the polling loop that does two things: | |
* | |
* 1. creates a forked task from the poll API call | |
* 2. passes in the forked task as an argument to a watching function that will cancel a task given a certain condition (i.e. an action to stopPolling is called) | |
* | |
* @method pollOrCancelEndpoint | |
*/ | |
export function *pollOrCancelEndpoint() { | |
const pollTask = yield fork(pollEndpointLoop); | |
yield watchCancelPoll(pollTask); | |
} | |
/* WATCHER FUNCTIONS */ | |
export function *watchCancelPoll(pollTask) { | |
yield takeLatest(types.STOP_POLLING, () => cancelPolling(pollTask)); | |
} | |
export function *watchPoll() { | |
yield takeLatest(types.WATCH_POLL_ENDPOINT, pollOrCancelEndpoint); | |
} | |
/** | |
* Call this method to initiate a redux-saga based polling function with an optional cancel state | |
* | |
* @method pollingSaga | |
*/ | |
export default function *pollingSaga() { | |
yield watchPoll(); | |
} |
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
export const STOP_POLLING = 'stop-polling'; | |
export const WATCH_POLL_ENDPOINT = 'watch-poll-endpoint'; | |
export const SET_ITEMS = 'set-items'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment