I want to perform an operation repeatedly, with an increasing timeout between each operation, until it succeeds or a certain amount of time elapses. How do I structure this
I think you can't do it on promise level - a promise isn't an operation, but is just a value that's going to arrive in the future, so you can't define a function typed Promise -> Promise that will achieve it.
You'd need to go one level down and define a function typed Operation -> Promise where Operation is itself typed () -> Promise. I assume the operation doesn't take any parameters - you can partially-apply them beforehand.
Here's a recursive approach that doubles the timeout on every run:
function RepeatUntilSuccess(operation, timeout) {
var deferred = Q.defer();
operation().then(function success(value) {
deferred.resolve(value);
}, function error(reason) {
Q.delay(timeout
.then(function() {
return RepeatUntilSuccess(operation, timeout*2);
}).done(function(value) {
deferred.resolve(value);
});
});
return deferred.promise;
}
Demo: http://jsfiddle.net/0dmzt53p/