My Synchronous Javascript Solution

I wrote about the problem I was having with the asynchronous (albeit single-threaded) nature of Javascript in my last post.

After looking at the options to make my code more clear when using asynchronous calls in Javascript, I’ve decided to take a simple approach. Instead of using one of the libraries, I’ve come up with what is basically a different way to format my code.

I can’t tell if this will be my long-term answer yet; I’ll just have to get further into the project and see how it goes.

So, here’s what I did. First, I wrote a function to do the actual asynchronous call. The only special thing about it is that it returns TRUE or FALSE, plus the return object.

PX.Rest = function (method, url, data, callback) {
    var successHandler, failureHandler, makeRequest, request;
    successHandler = function (o) {
        callback(true, o);
    };
    failureHandler = function (o) {
        callback(false, o);
    };

    makeRequest = function () {
        YAHOO.util.Connect.initHeader('Content-Type', 'text/json', true);
        request = YAHOO.util.Connect.asyncRequest(
            method,
            url,
            { success: successHandler,
              failure: failureHandler,
              connTimeout: 8000
            },
            data
        );
    };
    makeRequest();
};

Now, this lets me write my code like so:

// The first AJAX call.
PX.Rest(method, sUrl, jsonData,
    function (result, o) {
        if (result) {
            // If I'm here, it means the initial call was successful.

            // The second AJAX call (for example, to tag the record I just created).
            PX.Rest(method, sUrl, undefined,
                function (result, o) {
                    if (result) {
                        // The second call passed also
                    } else {
                        // The second call failed (after the first call succeeded)
                    }
                    // Code that runs no matter if the second call passes or fails
                }
            );
            // Code that runs when the first call passes but BEFORE the second one returns.
        } else {
            // The first call failed.
            // In this example, I don't do anything else.
        }
    }
);

Now it flows!  It’s almost like using nested if statements.

Here’s why I (think) it works:

  • The arguments are ordered in such a way  that the last one is the callback. This allows you to simply indent it in order to make it obvious you are inside conditional code.
  • The PX.Rest function from above returns TRUE or FALSE, which allows me to use a ‘If (request)’ in-line. That way, I can continue to simply indent and don’t have to create separate callbacks, define them ahead of time, etc.

I certainly don’t think this is a perfect solution, but it does allow me follow the flow of my code much more easily. I wouldn’t want to go more than two or three calls deep, though!

No comments yet

Leave a comment