Skip to content

Instantly share code, notes, and snippets.

@malte-wessel
Created February 5, 2017 12:59
Show Gist options
  • Save malte-wessel/c7ae203ef93b87a9d1968b15417e3d4a to your computer and use it in GitHub Desktop.
Save malte-wessel/c7ae203ef93b87a9d1968b15417e3d4a to your computer and use it in GitHub Desktop.
Higher order sagas
function doWhile(test) {
return function*(task, ...args) {
let result;
do {
result = yield call(task, ...args);
} while(yield test(result))
};
}
function retryable(maxRetries = 0) {
let retries = 0;
return function*(task, ...args) {
while(true) {
try {
yield call(task, ...args);
} catch(error) {
if (retries >= maxRetries) {
throw error;
}
retries++;
}
}
};
}
function cancelable(pattern) {
return function*(task, ...args) {
yield race([
take(pattern),
call(task, ...args)
]);
};
}
function onError(generator) {
return function*(task, ...args) {
try {
yield call(task, ...args);
} catch(error) {
yield call(generator, error);
}
};
}
function onCancel(generator) {
return function*(task, ...args) {
try {
yield call(task, ...args);
} catch(error) {
throw error;
} finally {
yield call(generator);
}
}
}
const poll = compose(
cancelable(action =>
action.type === 'ALLINONE_DEALS_POLL_CANCEL' &&
action.meta.itemId === itemId),
doWhile(response => response.pollingStatus !== 1),
onCancel(function* () {
yield put(cancelledAction());
}),
onError(function* (error) {
yield put(errorAction(error));
}),
retryable(5),
function* () {
yield call(api, apiOptions)
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment