JQuery嵌套$ .when以防止竞争条件

时间:2015-09-29 15:30:45

标签: jquery

所以我阅读了几篇关于如何执行此操作的帖子,如thisthis,但我确定了其他似乎适用于此内部LOB应用程序的内容。我在加载现有的“分配”之前异步加载数据库依赖项时遇到了问题(即,它在加载depts,division等之前尝试加载getAllocation(),getAssignedAssts()等等)所以我只是放了第二个$。何时/完成对依赖项的doneCallback内部的调用。像这样:

// assume allocationID is defined as allocation id we want to get from db
$.when(getDept(), getDivisions(), GetAvailComments(), getTargets())
.done(function msg1, msg2, msg3, msg4) {
    // initialize variables, knockout observables and observable arrays

    $.when(getAllocation(allocationID), getAssignedAssts(allocationID), getAssignedTeachers(allocationID))
    .done(function msg1, msg2, msg3) {
    });
})
.fail(function jqXHR, textStatus, errorThrown) {
    alert('Error getting Allocation: ' + jqXHR.status + ' ' + textStatus + ', ' + errorThrown + '<br />' + jqXHR.responseText);
});

假设存在getDept(),getDivisions()等,并返回一个像这样的ajax承诺:

function getDept() {
    var data = { plan_id: getParameterByName('plan_id') };

    return $.ajax({
        type: "POST",
        url: "Plan_Edit.aspx/PlanDept",
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    });
};

我的问题是这是否是坏的,如果是这样,那么“正确”的做法是什么?

1 个答案:

答案 0 :(得分:0)

我用Google搜索“jQuery嵌套时”,并找到this,我将其作为重新加入this jsfiddle的起点。我在上面实现的代码似乎很好,如本例所示 - 在第二个时调用jquery,直到第一个set完成后才调用,这正是我认为我想要的依赖性。这是javascript代码:

function message(html) {
    $('<div/>').html(html).appendTo($('body'));
}

function process(){  
    $.when(a1(), a2()).done(function(){
    message('a1 and a2 complete');

    $.when(a3(), a4()).done(function(){
        message('a3 and a4 complete');  
    });
    });
}

function a1(){
    var dfd = $.Deferred();        
    setTimeout(function(){ message("a1 done"); dfd.resolve();  },4000);    // can use console.log or message
    return dfd.promise();         
}

function a2(){
    var dfd = $.Deferred();
    setTimeout(function(){ message("a2 done"); dfd.resolve();  }, 2500);
    return dfd.promise();
}

function a3(){
    var dfd = $.Deferred();
    setTimeout(function(){ message("a3 done"); dfd.resolve();  }, 3000);
    return dfd.promise();
}

function a4(){
    var dfd = $.Deferred();
    setTimeout(function(){ message("a4 done"); dfd.resolve();  }, 2000);
    return dfd.promise();
}

process();