Question

I want to do a chain of $.when().then($when().then(...)) in jquery. I'm not used to the defered functions, first time using them.

I changed my code a bit my code to represent this situation:

function setenum(e)
{
    return $.ajax({
        url: SetPathUrl1(),
        type: 'GET',
        data: { isNew: e.isNew() },
        contentType: 'application/json; charset=utf-8',
        success: function (data, status, xhr) {
            /*My stuff*/
        },
        error: function (xhr, status, error) {
            /*My stuff*/
        }
    });
}

function setdropdown1(e)
{
    return $.ajax({
            url: SetPathUrl2(),
            type: 'GET',
            data: { isNew: e.isNew() },
            contentType: 'application/json; charset=utf-8',
            success: function (data, status, xhr) {
                /*Fill my first ddl based on enum*/
            },
            error: function (xhr, status, error) {
                /*My stuff*/
            }
        });
}

function setdropdown2(e)
{
    return $.ajax({
            url: SetPathUrl3(),
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            success: function (data, status, xhr) {
                /*Fill my second ddl based on enum*/
            },
            error: function (xhr, status, error) {
                /*My stuff*/
            }
        });
}

function DoOtherStuff(e)
{
    /**/
}

function MainNotWorking(ImportantModel)
{
    $.when(setenum(ImportantModel))
    .then(
        $.when(setdropdown1(ImportantModel),setdropdown2(ImportantModel))
        .then(
            function () {
                DoOtherStuff(e);
            }
        )
        );
}

function MainWorking(ImportantModel)
{

    $.when(setenum(ImportantModel),setdropdown1(ImportantModel),setdropdown2(ImportantModel))
    .then(
        function () {
            DoOtherStuff(e);
        }
    );

}

MainNotWorking : the order is not respected at all, set setdropdown1 and setdropdown2 are called sometimes before the setenum.

MainWorking: When I have only one level of when, then the function DoOtherStuff is called before all other functions, but it's only one level. I want to do multiple chain setenum before setdropdown1 and setdropdown2 and then finally DoOtherStuff.

Was it helpful?

Solution

Use $.when().done(callback)

function MainNotWorking(ImportantModel) {
    $.when(
        setenum(ImportantModel)
    ).done(function() {
        $.when(
            setdropdown1(ImportantModel), 
            setdropdown2(ImportantModel)
        ).done(DoOtherStuff);
    });
}

OTHER TIPS

First, you should pass a function reference to then:

.then(function() { ... })

What you are passing is executed immediately, instead of when the first function is finished.

That alone would be enough, but if you wanted to "flatten" out the chaining, you could do something like this:

$.when(
    setenum(ImportantModel)
).then(function() {
    return $.when(
        setdropdown1(ImportantModel),
        setdropdown2(ImportantModel)
    )
}).then(function() {
   DoOtherStuff(); 
});

Here's a demo: http://jsfiddle.net/44e5Y/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top