Search code examples
javascriptjqueryjquery-deferred

Preventing a function from running if a parallel function has already failed (using jQuery $.when())


I have a rather convoluted series of asynchronous functions that I am chaining with the help of jQuery Deferreds.

Essentially I have two parallel streams of functions, followed by functions that should be executed serially when the parallel streams have both finished. Here's an example (they are AJAX calls in real life):

function makeOmelette() {
    $.when(
        crackEggs().then(beatEggs),
        washTomatos().then(chopTomatos)
    ).then(mixEggsAndTomatos).then(fryEggsAndTomatos).done(function() {
        msg('Omelette is ready!');
    }).fail(function() {
        msg('Oh no, omelette fail!');
    });
}

The done() and fail() handlers at the end deal with success or failure. I would like the fail() handler to execute as soon as anything goes wrong, anywhere in the chain, and for all further execution to stop.

Mostly, this works - apart from one case. If there is a failure when cracking eggs, then the tomatos are still washed and chopped - even if the failure has already occurred by the time either of those tasks have started. Similarly, if there is a failure when washing tomatos, this doesn't stop the crackEggs and beatEggs functions from running.

You can see an example here.

My concern about this is that, in my real life code, I don't want the browser to be making AJAX calls to the server, which could potentially change state, if there is no point because the overall process has already failed.

Is there a way to do what I want? I suppose I could attach fail handlers to each of the parallel tasks individually, but I wondered if there was a less verbose/repetitive way.

Thanks!


Solution

  • Add a variable to the statuses. eg inside of done( var status = 1 ) and inside of fail( var status = 2 then put a simple statement before the running of the parallel function so that it won't run if status = 2.