jquery延迟与异步调用



请找到下面的代码片段:

.HTML:

<div>
<span> First Name : <input type="text" id="firstName" name="First Name"/></span>
</div>
<br/>
<div>
<span>Student Id: <input type="text" id="studentId" name="studentId"/></span>
<span>Teacher Id: <input type="text" id="teacherId" name="teacherId"/></span>
</div>
<br/>
<div>
<span>Student Name : <input type="text" id="stdLastName" name="stdLastName"/></span>
<span>Student Age :<input type="text" id="stdAge" name="stdAge"/></span>
</div>
<br/>
<div>
<span>Teacher Name : <input type="text" id="tchrLastName" name="tchrLastName"/></span>
<span>Teacher Age : <input type="text" id="tchrAge" name="tchrAge"/></span>
</div>
<br/>
<input type="button" value="Submit" id="submit"/>

Javascript:

$('#firstName').focus();
var d1= new $.Deferred();
$('#firstName').blur(populatePage());
//called on blur of first name 
function populatePage() {
$.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....');
d1.resolve();
});
return d1;
}  
//first ajax call
function populateStdDetails() {
if($('#firstName').val() != '' && $('#studentId').val() !='') {
return $.ajax({
url : '/someURL?studentId='+studentId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
}
}
//second ajax call
function populateTchrDetails() {
if($('#firstName').val() != '' && $('#teacherId').val() !='') {
return $.ajax({
url : '/someURL?teacherId='+teacherId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
}
}
$('#submit').click(function(e){
//wait for the ajax calls to be completed
$.when(populatePage()).done(function(e){
console.log('All done !!!!');
//Move to next page;
});
});

"名字"文本字段附加了一个 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();
});

好的,如果您希望在焦点离开 #firstname 时调用populatePage(),并且如果用户还单击了提交按钮并且您希望提交操作等待该模糊操作完成,则可以执行以下操作:

$('#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
});
});

我在您的承诺处理代码中更新的内容:

  1. 直接使用$.ajax()承诺,而无需将它们包装在另一个承诺中。
  2. 直接使用$.when()承诺,而无需将它们包装在另一个承诺中。
  3. 使用if语句决定是否执行异步操作时,通常最好在elsearm 中返回一个 promise,以便您的函数始终返回 promise。 如果在else子句中没有其他事情可做,那么在 jQuery 中返回已经解析的承诺的快捷方式就是return $.when();
  4. 请注意,.done()特定于 jQuery 而不是标准的 promise 行为。 如果你已经在jQuery 3.x或更高版本上,那么你可能应该切换到.then()然后你的承诺将表现得像承诺标准。

最新更新