我有一个函数可以在按下按钮时验证某些字段。首先检查用户名和密码是否可信。如果密码是适当安全的话。然后,如果它与确认密码框匹配。但是,似乎在第一个函数中的警报弹出之前,检查用户是否是真实的ajax似乎没有完成。
$(document).ready(function() {
$('#submit_pw_ch').on('click', function(){
var alertString = "Please correct the following errors: \n"
//current username and password are correct
var vUsr = valUsr();
//new password is sufficiently secure
var vPwd = valPwd();
//confirmation of new password is same as previous box
var sPwd = samePwd();
console.log('valid user : ' + vUsr + ' valid password : ' + vPwd + ' same password : ' + sPwd);
//append appropriate warnings to alert string
if ( !vUsr ) { alertString += "-Your current username and password are invalid. \n"; }
if ( !vPwd ) { alertString += "-The new password you have selected is not strong enough. \n"; }
if ( !sPwd ) { alertString += "-The confirmation of your new password does not match the previous entry. \n"; }
if ( !vUsr || !vPwd || !sPwd ) {
alert(alertString);
return false;
} else {
//change password
}
});
});
因此,检查该行的var vUsr = valUsr();
调用
function valUsr() {
var un = $('#uNameInput').val();
var pw = $('#uPwdInput').val();
//return value
var validUsr = false;
$.ajax({
type: "post",
url: "queries/confirm_user.php?<?=time()?>",
data: "un=" + un + "&pw=" + pw,
dataType: "json",
success: function (returnedData) {
console.log(returnedData)
if (data == 'true') {
validUsr = true;
} else {
validUsr = false;
}
}
});
return validUsr;
}
不知怎的,虽然警报没有等待ajax完成获取它的数据。在我取消警告框后,console.log(returnedData)
功能中的valUsr()
出现在控制台中。为什么会这样?我该怎样预防呢?谢谢!
答案 0 :(得分:2)
托马斯,
你需要迎合ajax固有的异步性,换句话说,你需要等到对ajax请求的响应已经到来,然后再决定做什么。
jQuery's Deferreds(和承诺)允许我们编写简单的代码,但Deferreds一开始往往会让你大吃一惊,至少非常轻微。
对于像这样的问题,没有独特的方法可以使用Deferreds,但这里只有一个。
$(document).ready(function() {
$('#submit_pw_ch').on('click', function() {
var form = this.form; //the form containing the submit button and the fields .
//`alertArr` is an array to which messages will be added.
var alertArr = ["Please correct the following errors:"];
//`addAlert` will be called from a `Deferred.resolveWith(this, ...)` statement.
//The context, `this`, is unused.
function addAlert(index, txt) {
alertArr[index] = txt;
}
//`compositeAction` will be called from a promise.done() statement.
function compositeAction() {
//first filter out null messages (ie. validation successes) from alertArr.
var message = $.map(alertArr, function(txt, i){
return txt || null;
});
if(message.length > 1) {
//then alert the complete message with line breaks
alert(message.join("\n"));
} else {
//submit the form to change the password
//or another ajax call as required
form.submit();
}
}
// Invoke ajax validators and assign returned promises.
// An index is passed, so the text messages can be displayed in a logical order,
// regardless of the order in which the validation promises are resolved.
//If we didn't care about the order of the messages then the code would be slighly simpler.
var vUsr = valUsr(0),
vPwd = valPwd(1),
sPwd = samePwd(2);
//All validations adopt a similar pattern regardless of whether ajax is involved or not.
//Here, we establish what is to be done when the promise are resolved, or
//what is to be done immediately if the promise are alrady resolved.
vUsr.done(addAlert);
vPwd.done(addAlert);
sPwd.done(addAlert);
//At this stage, `addAlert` will contain entries for successful as well as unsuccessful validations. Successful entries will be filtered out by `compositeAction`
//Establish what is to be done when all three promises are resolved.
$.when(vUsr, vPwd, sPwd).done(compositeAction);
//Return false unconditionally
return false;
});
function valUsr(index) {
var messages = {
validated: '',//important - this message must be an empty string - do not change
notValidated: '- Your current username and password are invalid.',
ajaxError: '- Validation error: username and password.'
};
//Create a Deferred object, which will be resolved in response to several different outcomes.
var def = $.Deferred();
$.ajax({
type: "post",
url: "queries/confirm_user.php?<?=time()?>",
data: {
'un': $('#uNameInput').val(),
'pw': $('#uPwdInput').val()
},
dataType: "json",
success: function (returnedData) {
if (returnedData == 'true') {
def.resolveWith(this, [index, messages.validated]);
} else {
def.resolveWith(this, [index, messages.notValidated]);
}
},
error: function() {
def.resolveWith(this, [index, messages.ajaxError]);
}
});
return def.promise();//Return a promise derived from the as yet unresolved Deferred.
}
function samePwd(index) {
var pw1 = $('#uPwdInput').val();
var pw2 = $('#uPwdInput2').val();
var errMessage = (pw1 === pw2) ? '' : '-The confirmation of your new password does not match the previous entry';
var def = $.Deferred();//Create a Deferred object, which will be resolved immediately
def.resolveWith(this, [index, errMessage]);
return def.promise();//Return a promise derived from the already resolved Deferred.
}
});
valPwd()
的格式与valUsr()
或samePwd()
的格式相同,具体取决于是否涉及ajax。
答案 1 :(得分:1)
在成功回调中完成ajax请求后,您需要检查之后的其他字段的验证。您可以关闭同步请求,但浏览器将冻结'直到它获得一个,不建议。
您需要重新调整您的电话以反映这一点;我建议他们一旦完成输入密码并且字段模糊,就发送请求进行检查。这样,如果有任何错误,您将能够阻止表单结束时的等待时间。