Mochikit notes

I never thought to be writing real-time control applications in Javascript, but I suppose stranger things have happenned. Here are a few things I've learned that were not clear to me from the main Mochikit documentation.


1. Async module - Deferred callbacks

Normally, a Deferred callback (or errback) function returns a value that is passed as the parameter to the next callback in the chain, or which becomes the final result of the Deferred operation. Usually, this will simply be a copy of the supplied parameter. But if the callback has taken an action that effectively changes the original response (e.g. a local default value provider might translate an HTTP 404 response into a new HTTP 200 response with the default content), then new result can be passed onward for subsequent callback handlers to process.

A Deferred operation eventually yields a final result, which is constructed by the sequenced application (composition) of funtions in the callback chain. The result of a callback invoked by mainline code is discarded (usually being consumed by that final callback function), but when a new Deferred is created by a callback function, its final result can be passed pack to the original Deferred object.

Thus, a Deferred callback (or errback) function may itself initiate a new operation that completes asynchronously, which in turn further delays completion of the original request (e.g. a web request that returns an HTTP redirect response may be used to trigger a new request to the redirected URI that is used to fulfil the original request). In such cases, if the callback returns a new Deferred object, the callback chain is suspended until that Deferred object has yielded a final result; that result is then passed onward down the original callback chain.

2. Timeout of HTTP requests

I found some off-the-cuff code for timing out operations on the web submitted by Mochikit's author, Bob Ippolito, but I still had to dig around a bit to make an HTTP request with timeout (largely due to unfamiliarity with Javascript). Anyway, I've constructed some code that seems to work, which I thought might be a useful example for others to hack at:

// Function behaves a bit like 'doSimpleXMLHttpRequest', except that it 
// takes a timeout (seconds) argument and completes the request with a 
// CancelledError condition if the HTTP operation does not complete 
// within the specified time interval
function doTimedXMLHttpRequest(uripath, timeout)
    // logDebug("doTimedXMLHttpRequest: ", uripath, ", timeout: ", timeout) ;
    return addTimeout(doSimpleXMLHttpRequest(uripath), timeout) ;

// Accepts a deferred value, and returns a deferred that behaves
// just like the original except that it is cancelled if it fails
// to complete in the specified number of seconds.
function addTimeout(deferred, timeout)
    // logDebug("addTimeout: ", timeout) ;
    // Define local canceller function, bound to deferred
    var canceller = callLater(timeout,
        function ()
            // Cancel the deferred after timeout seconds
            // logDebug("** Timeout") ;
            deferred.cancel() ;
            } ) ;
        function (res) 
            // If the deferred fires, cancel the timeout
            // logDebug("** Cancel timeout") ;
            canceller.cancel() ;
            return res;
            } ) ;
    return deferred

-- GrahamKlyne 2006-02-23 14:25:54

Creative Commons License
The content of this wiki is licensed under the Creative Commons Attribution-ShareAlike 2.0 England & Wales Licence.

OSS Watch is funded by the Joint Information Systems Committee (JISC) and is situated within the Research Technologies Service (RTS) of the University of Oxford.