Thursday, December 11, 2014

Failing on Timeout for Any JavaScript Promise

I will soon be building an asynchronous promise based library, because it will make me happy. Here is a taste.

This is a function that takes a delay, an arbitrary promise, a timeout, a timeout function, and a timeout error object. This copy also takes a "q" and "timeout" because I was working with Angular and the code is slightly Angular focussed although it could be adapted easily. The function will complete the promise as normal unless too much time passes and it that case it will reject the promise using a timeout. The nice thing is that this works for ANY promise and you can just seamlessly wrap any promise.

I put in the timeOutFn because in my case I needed some cleanup done when a timeout occurred.

function FailOnTimeout(q,timeout,delay,promise, timeOutFn, timeOutError) {
    var deferred = q.defer();
    var timedOut = false;
    var timedOutPromise = timeout(function() {
        out("in timout function");
        timedOut = true;
        if (timeOutFn) {
            timeOutFn();
        }
        var error = timeOutError || new Exception("Time out occurred");
        deferred.reject(error);
    }, delay)
    promise.then(function(data) {
        out("in success handler");
        if (!timedOut) {
            out("running success handler")
            timeout.cancel(timedOutPromise);
            deferred.resolve(data);
        }
    }, function (error) {
        out("in error handler");
        //out("in error part");
        if (!timedOut) {
            out("running error handler");
            timeout.cancel(timedOutPromise);
            deferred.reject(error);
        }
    })
    return deferred.promise;
}

You could combine this technique with Proxies and make it so that every request that took too long in production got logged to some sort of logging server. (Although there are better ways to do this kind of thing)

No comments:

Post a Comment