Created
September 1, 2016 23:03
-
-
Save anyley/a2258482b9b6fdb6bb0d0293471eb341 to your computer and use it in GitHub Desktop.
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
const { | |
createStore, | |
combineReducers, | |
applyMiddleware, | |
bindActionCreators | |
} = Redux | |
const { default: createSagaMiddleware, effects } = ReduxSaga | |
const { take, put, call, fork, join, cancel, race } = effects | |
/////////////////////////////////////////////////////////////////// | |
// | |
// mimics a remote source | |
// | |
function fakeSource(url) { | |
let listener, count = 0 | |
// send a message 5 times each second | |
const iv = setInterval(() => { | |
if(count < 5) | |
listener({ data: `"${url}/${++count}"` }) | |
else { | |
clearInterval(iv) | |
listener({data: null}) | |
} | |
}, 1000) | |
return { | |
set onmessage(l) { | |
listener = l | |
} | |
} | |
} | |
///////////////////////////////////////////////////////// | |
// | |
// our API function | |
// creates a message iterator: {nextMessage: () -> Promise} | |
// Promise that will resolve to the next message | |
function createSource(url) { | |
const source = fakeSource(url) | |
let deferred | |
source.onmessage = event => { | |
if(deferred) { | |
deferred.resolve(JSON.parse(event.data)) | |
deferred = null | |
} | |
} | |
return { | |
nextMessage() { | |
if(!deferred) { | |
deferred = {} | |
deferred.promise = | |
new Promise(resolve => deferred.resolve = resolve) | |
} | |
return deferred.promise | |
} | |
} | |
} | |
/////////////////////////////////////////////////////////////// | |
// | |
// Actions | |
// | |
const APP_LOADED = 'APP_LOADED' | |
const appLoaded = () =>({type: APP_LOADED}) | |
const receive = (message) => ({type: 'RECEIVE', message}) | |
/////////////////////////////////////////////////////////////// | |
// | |
// Reducers | |
// | |
function messageList(state = [], action) { | |
if(action.message) | |
return [...state, action.message] | |
return state | |
} | |
const rootReducer = combineReducers({ | |
messageList | |
}) | |
/////////////////////////////////////////////////////////////// | |
// | |
// Sagas | |
// | |
function* watchMessages(msgSource) { | |
console.log('begin receive messages') | |
let msg = yield call(msgSource.nextMessage) | |
while(msg) { | |
yield put(receive(msg)) | |
msg = yield call(msgSource.nextMessage) | |
} | |
console.log('done receive messages') | |
} | |
function* getMessagesOnLoad() { | |
yield take('APP_LOADED') | |
const msgSource = yield call(createSource, '/myurl') | |
yield fork(watchMessages, msgSource) | |
} | |
const saga = getMessagesOnLoad | |
/////////////////////////////////////////////////////////////// | |
// | |
// Create the store. Log states into the console | |
// | |
const sagaMiddleware = createSagaMiddleware() | |
const store = createStore( | |
rootReducer, | |
applyMiddleware(sagaMiddleware) | |
) | |
sagaMiddleware.run(saga) | |
let lastState | |
store.subscribe(() => { | |
const state = store.getState() | |
if(state !== lastState) { | |
lastState = state | |
console.log(lastState.messageList) | |
} | |
}) | |
/* test */ | |
store.dispatch(appLoaded()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment