Skip to content

Instantly share code, notes, and snippets.

@stormslowly
Forked from domenic/promise-retryer.js
Created June 25, 2014 23:11
Show Gist options
  • Save stormslowly/c1b44aeaa0c99c193847 to your computer and use it in GitHub Desktop.
Save stormslowly/c1b44aeaa0c99c193847 to your computer and use it in GitHub Desktop.
"use strict";
// `f` is assumed to sporadically fail with `TemporaryNetworkError` instances.
// If one of those happens, we want to retry until it doesn't.
// If `f` fails with something else, then we should re-throw: we don't know how to handle that, and it's a
// sign something went wrong. Since `f` is a good promise-returning function, it only ever fulfills or rejects;
// it has no synchronous behavior (e.g. throwing).
function dontGiveUp(f) {
return f().then(
undefined, // pass through success
function (err) {
if (err instanceof TemporaryNetworkError) {
return dontGiveUp(f); // recurse
}
throw err; // rethrow
}
});
}
// Analogous synchronous code:
function dontGiveUpSync(fSync) {
try {
return fSync();
} catch (err) {
if (err instanceof TemporaryNetworkError) {
return dontGiveUpSync(fSync);
}
throw err;
}
}
// Note how we created this powerful abstraction without ever using ANY aspect of the promise implementation
// besides the Promises/A "thenable"-ness. In particular, we had NO need of a deferred library, and we can
// interoperate with ANY promise library, returning to the caller the same type of promise we received (i.e.
// we don't assimilate When.js promises into Q promises in order to work with them).
// An example of a library that makes extensive use of this property is
// https://github.com/domenic/chai-as-promised/
// Unfortunately such composable patterns are impossible with jQuery promises, since there is no way to trap
// and rethrow errors. jQuery only allows you to catch explicit rejections, but does not allow access to
// thrown exceptions, and furthermore you cannot transition into a rejected state by (re)throwing or out
// of one by choosing not to rethrow: in a jQuery promise's fulfilled and rejected callbacks, you need to
// manually use jQuery's deferred library to transition state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment