Skip to content

Instantly share code, notes, and snippets.

@zushenyan
Created July 15, 2016 18:02
Show Gist options
  • Save zushenyan/cddc1c7cebcd359b4692c948af56e3a5 to your computer and use it in GitHub Desktop.
Save zushenyan/cddc1c7cebcd359b4692c948af56e3a5 to your computer and use it in GitHub Desktop.
import _ from "lodash";
import {fn as isGeneratorFn} from "is-generator";
const generatorMiddleware = store => next => action => {
let {dispatch} = store;
let generator = findGenerator(action);
if(isGeneratorFn(action)){
return runGenerator(dispatch, action, action);
}
else if(generator){
return runGenerator(dispatch, action, generator);
}
return next(action);
};
export default generatorMiddleware;
/*
helper zone
*/
function runGenerator(dispatch, action, generator){
let iterator = generator();
function handle(result, ite){
let value = result.value;
if(value){
if(typeof value === "object" && "then" in value){
value.then((res) => dispatchActualAction(dispatch, action, res));
}
else{
dispatchActualAction(dispatch, action, value);
}
}
if(result.done){ return Promise.resolve(value); }
return Promise.resolve(value).then((res) => handle(ite.next(res), ite));
}
return handle(iterator.next(), iterator);
}
function findGenerator(action, onFound){
if(action.performAction && isGeneratorFn(action.performAction)){
onFound && onFound(action);
return action.performAction;
}
else if(action.performAction){
return findGenerator(action.performAction, callbackOnFound);
}
return null;
}
function dispatchActualAction(dispatch, action, actualAction){
if(isGeneratorFn(action)){
dispatch(actualAction);
}
else{
let clonedAction = _.cloneDeep(action);
findGenerator(clonedAction, (parentAction) => { parentAction.performAction = actualAction; });
dispatch(clonedAction);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment