Ajax函数在第二次运行之前未完成

时间:2012-12-13 13:16:13

标签: javascript ajax jquery

我有一个看起来像这样的Ajax函数

function PersonAtlLawUpdate(personRef) {
var selectionPanel = $('div#SelectionPanel');
var fromdate = selectionPanel.find('input#FromDateTextBox')[0].defaultValue;
var timeSpan = selectionPanel.find('select#TimeSpanDropdownList').data('timespanvalue');
var url = "MonthOverview.aspx/OnePersonAtlLawUpdate";
$.ajax({
    url: url,
    data: JSON.stringify({ personRef: personRef, fromdate: fromdate, timespan: timeSpan }),
    type: "POST",
    contentType: "application/json",
    dataType: "JSON",
    context: document.body,
    success: function (atlError) {
        changePersonAtlStatusIcon(atlError, personRef);
    },
    error: function (xhr, status, errorThrown) {
        //alert(errorThrown + '\n' + status + '\n' + xhr.statusText);
    }
});

}

在一个函数中,我需要像这样运行两次:

    PersonAtlLawUpdate($(gMarkedCell).parent("tr").attr("personref"));
    PersonAtlLawUpdate(pRef);

问题可能是在某些情况下不能100%工作。 dom没有更新其中一个功能。我认为这是因为另一个“覆盖”了它。

那么如何确保第一个“PersonAtlLawUpdate”在第一个完成后运行?延迟它似乎不错。在ajax调用中将async设置为false是一个很好的解决方案吗?

EDIT, 像这样走路并在我的成功中放置了console.log。但“全部完成”将首先运行:

$.when(PersonAtlLawUpdate($(gMarkedCell).parent("tr").attr("personref")), PersonAtlLawUpdate(pRef)).then(function (){console.log("all complete")});

3 个答案:

答案 0 :(得分:1)

您可以使用回调函数,以便在第一个函数执行后立即执行:

PersonAtlLawUpdate($(gMarkedCell).parent("tr").attr("personref"), function(){
  PersonAtlLawUpdate(pRef);
});

或许您可以重新考虑这个问题,并提出一个不需要两次调用相同功能的解决方案。也许你真的不需要这样做。

答案 1 :(得分:0)

我认为@Kyokasuigetsu建议您需要更改PersonAtlLawUpdate方法,以便接受可选的第二个参数:需要在成功回调中调用的回调函数。

function PersonAtlLawUpdate(personRef, cbFunc) {
var selectionPanel = $('div#SelectionPanel');
var fromdate = selectionPanel.find('input#FromDateTextBox')[0].defaultValue;
var timeSpan = selectionPanel.find('select#TimeSpanDropdownList').data('timespanvalue');
var url = "MonthOverview.aspx/OnePersonAtlLawUpdate";
$.ajax({
    url: url,
    data: JSON.stringify({ personRef: personRef, fromdate: fromdate, timespan: timeSpan }),
    type: "POST",
    contentType: "application/json",
    dataType: "JSON",
    context: document.body,
    success: function (atlError) {
        changePersonAtlStatusIcon(atlError, personRef);
        if (cbFunc != null)
            cbFunc();
    },
    error: function (xhr, status, errorThrown) {
        //alert(errorThrown + '\n' + status + '\n' + xhr.statusText);
    }
});

而不是拨打电话;

PersonAtlLawUpdate($(gMarkedCell).parent("tr").attr("personref"), function(){
  PersonAtlLawUpdate(pRef);
});

答案 2 :(得分:0)

如果return $.ajax来自PersonAtLawUpdate功能,您的示例将正常运行。

$.when需要对ajax调用的引用,因此请确保从函数中返回Deferred(ajax调用)

function PersonAtlLawUpdate(personRef) {
    var selectionPanel = $('div#SelectionPanel');
    var fromdate = selectionPanel.find('input#FromDateTextBox')[0].defaultValue;
    var timeSpan = selectionPanel.find('select#TimeSpanDropdownList').data('timespanvalue');
    var url = "MonthOverview.aspx/OnePersonAtlLawUpdate";
    //SEE THE NEXT LINE
    return $.ajax({
        url: url,
        data: JSON.stringify({ personRef: personRef, fromdate: fromdate, timespan:  timeSpan }),
        type: "POST",
        contentType: "application/json",
        dataType: "JSON",
        context: document.body,
        success: function (atlError) {
            changePersonAtlStatusIcon(atlError, personRef);
        },
        error: function (xhr, status, errorThrown) {
            //alert(errorThrown + '\n' + status + '\n' + xhr.statusText);
        }
    });
}

使用

$.when(PersonAtLawUpdate(ref1), PersonAtLawUpdate(ref2)).done(function(xhrRef1, xhrRef2) {
    //do stuff w/ results from both calls
    //if you return something from the server, 
    //the results will be available in xhrRef1[0] 
    //and xhrRef2[0], respectively (order they 
    //appear in the when(), not in the order they execute
});