Question: 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 with promises in Q?

Answer: 
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/>
1. Assign a boolean variable for "all process timeout".
2. Call window's setTimeout to make that variable 'false' after that "all process timeout".
3. Call promise operation with a timeout.
4. If it succeeds no problem.
5. If it fails: In promise's error handler, call promise function again with an increased timeout if the boolean variable is true.

Something like this:

```
var goOn= true;

setTimeout(function () {
    goOn= false;
}, 30000); // 30 seconds -- all process timeout

var timeout = 1000; // 1 second

(function () {
    var helperFunction = function () {

        callAsyncFunc().then(function () {
            // success...
        }, function () {
            // fail
            if (goOn) {
                timeout += 1000; // increase timeout 1 second
                helperFunction();
            }
        }).timeout(timeout);

    }
})();

```