Ajax jquery延迟异步调用

Ajax jquery延迟异步调用,ajax,jquery-deferred,Ajax,Jquery Deferred,请查找以下代码段: HTML: “名字”文本字段附加了一个onblur事件,该事件在通常情况下可以正常工作,但当焦点集中在“名字”上并单击“提交”时,将调用提交函数,而不是等待onblur事件完成。您在超时函数中将deferred.resolve放置在错误的位置。这样做: function doSomething(deffered) { $('#log').append('doSomething'); deferred.resolve(); return deferred

请查找以下代码段:

HTML:


“名字”文本字段附加了一个onblur事件,该事件在通常情况下可以正常工作,但当焦点集中在“名字”上并单击“提交”时,将调用提交函数,而不是等待onblur事件完成。

您在超时函数中将deferred.resolve放置在错误的位置。这样做:

function doSomething(deffered) {
    $('#log').append('doSomething');
    deferred.resolve();
    return deferred;
};

function ajaxRequests1(deferred) {
    setTimeout(function(){
        $('#log').append('......ajaxRequests1');
        deferred.resolve(); 
    }, 1000);
    return deferred;
};

function ajaxRequests2(deferred) {
   setTimeout(function(){
        $('#log').append('.....ajaxRequests2');
        deferred.resolve();
   }, 5000); 
   return deferred;
};

var func1 = function () {
        var promise = new $.Deferred();
        ajaxRequests1(promise);
        return promise;
    }

var func2 = function () {
        var promise = new $.Deferred();
        ajaxRequests2(promise);
        return promise;
}

var stepFinal = function() {
       var promise = new $.Deferred();
       doSomething(promise);
       return promise;
}

$.when(func1().promise(), func2().promise())
    .done(function () {
            stepFinal().done();
    });
好的,如果希望在focus离开firstname时调用populatePage,并且如果用户还单击了submit按钮,并且希望submit操作等待模糊操作完成,则可以执行以下操作:

$('#firstName').blur(function(e) {
    // call populatePage and set the resulting promise as a data item so
    // the submit handler can get access to it
    var self = $(this);
    var p = populatePage();
    self.data("blurPromise", p);

    // when this promise is done, clear the blurPromise
    p.always(function() {
        self.removeData("blurPromise");
    });
});

//called on blur of first name 
function populatePage() {
    return $.when(populateStdDetails(),populateTchrDetails()).done(function(resp1, resp2){
        $('#stdLastName').val(resp1[0].stdName);
        $('#stdAge').val(resp1[0].age);
        $('#tchrLastName').val(resp2[0].stdName);
        $('#tchrAge').val(resp2[0].age);
        console.log('All details populated....');
    });
}  

//first ajax call
function populateStdDetails() {
    if($('#firstName').val() != '' && $('#studentId').val() !='') {
        return $.ajax({
            url : '/someURL?studentId='+studentId+'&firstName='+firstName,
            type :'GET',
            contentType:'json'
        });
    } else {
        // just return already resolved promise
        return $.when();
    }
}

//second ajax call
function populateTchrDetails() {
    if($('#firstName').val() != '' && $('#teacherId').val() !='') {
        return $.ajax({
            url : '/someURL?teacherId='+teacherId+'&firstName='+firstName,
            type :'GET',
            contentType:'json'
        });
    } else {
        return $.when();
    }
}

$('#submit').click(function(e){
    // get blur promise or dummy resolved promise
    var p = $("#firstName").data("blurPromise") || $.when();
    p.then(function() {
        // do your submit logic here
        // The onBlur handler is done now
    });
});
我在您的承诺处理代码中更新的内容:

直接使用$.ajax承诺,而无需将其包装在另一个承诺中。 直接使用$.when承诺,而不使用另一个承诺。 当使用if语句决定是否执行异步操作时,通常最好在else arm中也返回一个承诺,以便函数始终一致地返回一个承诺。如果else子句中没有其他操作,那么在jQuery中返回已解析的承诺的快捷方式就是只返回$.when;。 请注意,.done是特定于jQuery的,而不是标准的承诺行为。如果您已经使用jQuery3.x或更高版本,那么您可能应该切换到。然后,您的承诺就会像承诺标准一样。
注意,在实际代码中,jQuery中的ajax请求已经返回了它们自己的承诺,所以您不需要将它们包装在另一个承诺中。如果您向我们展示您的真实代码,我们实际上可以分享如何最好地使用真实代码的承诺。虚构代码的理论问题很少像真实代码那样有价值,因为贡献者可以向您展示所有您可以做得更好的东西。@jfriend00:请找到我描述实际需求的地方:该代码有很多错误。首先,它充满了挑战。如果你按照这里的发帖指南把这些代码放到你的问题中,我们可以告诉你很多更好的方法来做你正在做的事情。正如我所怀疑的那样,您根本不需要创建新的承诺,因为您已经从$.ajax调用中获得了可以直接使用的承诺。是的,我同意您的看法,不需要从ajax解析承诺,因为它可以直接使用,但实际上我们已经在ajax上构建了一个包装器,它只允许调用方实现回调。无论如何,我已经用更实际的代码片段更新了原始问题。谢谢您的回答。由于第一个文本字段附加了一个OnFLUR事件,请考虑当焦点位于字段的第一个名称时,会发生什么,并单击提交。将调用onblur事件以及Submit函数。我希望onblur函数在执行submit函数之前完成。你认为e.preventDefault可以防止模糊事件吗?@diptesh2007-我试图理解这里的所有用例。如果关注点是名字,用户单击submit按钮,是否只调用populatePage一次,然后在完成后提交表单?如果用户位于其他字段上,是否还要在提交前调用populatePage一次,然后在完成后提交表单?那么,你只是想在失去焦点或提交时调用populatePage吗?还有,有没有实际的计划?你的HTML没有显示这些标记。我希望populatePage只在名字字段的onblur期间调用,这是当前正在发生的。在提交过程中,我只想调用提交函数,而不管哪个字段有焦点,但如果名字有焦点并且单击了提交,则当前将调用填充页面。在本例中,表单是通过ajax提交的,而不是通过默认的表单操作提交的。@diptesh2007-好的,我完全修改了我的答案,以满足您的要求。@diptesh2007-这是否回答了您的问题?如果是这样,您可以通过单击答案左侧的绿色复选标记向社区表明这一点,这也将为您赢得一些声誉点数。
function doSomething(deffered) {
    $('#log').append('doSomething');
    deferred.resolve();
    return deferred;
};

function ajaxRequests1(deferred) {
    setTimeout(function(){
        $('#log').append('......ajaxRequests1');
        deferred.resolve(); 
    }, 1000);
    return deferred;
};

function ajaxRequests2(deferred) {
   setTimeout(function(){
        $('#log').append('.....ajaxRequests2');
        deferred.resolve();
   }, 5000); 
   return deferred;
};

var func1 = function () {
        var promise = new $.Deferred();
        ajaxRequests1(promise);
        return promise;
    }

var func2 = function () {
        var promise = new $.Deferred();
        ajaxRequests2(promise);
        return promise;
}

var stepFinal = function() {
       var promise = new $.Deferred();
       doSomething(promise);
       return promise;
}

$.when(func1().promise(), func2().promise())
    .done(function () {
            stepFinal().done();
    });
$('#firstName').blur(function(e) {
    // call populatePage and set the resulting promise as a data item so
    // the submit handler can get access to it
    var self = $(this);
    var p = populatePage();
    self.data("blurPromise", p);

    // when this promise is done, clear the blurPromise
    p.always(function() {
        self.removeData("blurPromise");
    });
});

//called on blur of first name 
function populatePage() {
    return $.when(populateStdDetails(),populateTchrDetails()).done(function(resp1, resp2){
        $('#stdLastName').val(resp1[0].stdName);
        $('#stdAge').val(resp1[0].age);
        $('#tchrLastName').val(resp2[0].stdName);
        $('#tchrAge').val(resp2[0].age);
        console.log('All details populated....');
    });
}  

//first ajax call
function populateStdDetails() {
    if($('#firstName').val() != '' && $('#studentId').val() !='') {
        return $.ajax({
            url : '/someURL?studentId='+studentId+'&firstName='+firstName,
            type :'GET',
            contentType:'json'
        });
    } else {
        // just return already resolved promise
        return $.when();
    }
}

//second ajax call
function populateTchrDetails() {
    if($('#firstName').val() != '' && $('#teacherId').val() !='') {
        return $.ajax({
            url : '/someURL?teacherId='+teacherId+'&firstName='+firstName,
            type :'GET',
            contentType:'json'
        });
    } else {
        return $.when();
    }
}

$('#submit').click(function(e){
    // get blur promise or dummy resolved promise
    var p = $("#firstName").data("blurPromise") || $.when();
    p.then(function() {
        // do your submit logic here
        // The onBlur handler is done now
    });
});