jQuery 使用 $.get 的延迟变量
jQuery deferred variable using $.get
我迷路了,不确定要查找什么。我知道这可能与 jQuery 承诺有关。所以,开门见山,我正在尝试 return 一个 "pass" 变量作为布尔值来检查电子邮件是否有效。它不是传递带有值 = "asdf" 的 false,而是传递 true。我知道这是因为异步请求,我只是不确定如何推迟该变量。代码如下:
console.log( this.newValidate($('#forgottenPwdForm'))); // Returns true
newValidate: function(form){
var $form = form,
errmsg = function(msg){
return '<span class="error" style="text-align:right; margin: 2px 15px; color:red;">' + msg + '</span><br/>';
};
// Check email / username
// Needs to run 2 validations. Is the email valid? And is it duplicate if valid
if($form.find('.email').length)
$form.find('.email').each(function(){
var email = escape($(this).val().trim()),
valid = true,
duplicate = false,
pass = true;
// Check if email is valid
$.when(
$.get('/service/account/ajaxdata?method=validemail&emailaddr='+email, function(res){
console.log(res);
valid = res;
}),
$.get('/subscribe/check_email?email=' + email, function(data) {
if(data){
duplicate = false; }
})
).then(function(){
if(valid == 0){
var error = errmsg("Email is not valid.");
pass = false;
console.log(pass);
}
else {
// Now that the email is valid, we need to check if it's duplicate
if(duplicate == false) {
$('.email').addClass('emailError');
pass = false;
}
else {
if($('.email').hasClass('emailError')) {
$('.email').removeClass('emailError');
$('.email').removeClass('error');
}
pass = true;
}
}
});
if(pass == false) return pass;
});
代码 return 为真,而应 return 为假。同样,我知道这与 $.get 请求和变量超出范围有关,我只是不确定如何推迟它。
您需要使用结果执行回调方法,而不是设置变量。
代码是 运行 异步的,因此执行会一直持续到最后而不执行任何验证代码,这就是为什么您总是得到 true 的原因。
所以不要说 pass = true|false
你需要做类似的事情:MyCallBackFunction(true|false)
在 newValidate()
中,您正在使用承诺,因此 return 承诺 。请不要试图传入回调“because then you lose exception bubbling (the point of promises) and make your code super verbose”(@Esailija)。
这是对 promises 的相当具有挑战性的介绍,因此有很多评论:
newValidate: function($form) {
var $emailElements = $form.find('.email');
var promises = $emailElements.map(function(index, el) { // Use `.map()` to produce an array of promises.
var email = escape($(el).val().trim());
return $.when(
$.get('/service/account/ajaxdata?method=validemail&emailaddr=' + email), // no direct callback here ...
$.get('/subscribe/check_email?email=' + email) // ... or here.
).then(function(valid, unique) { // Simple! The two $.get() responses appear hear as arguments.
// The question's `data` appears to be a `unique` indicator (ie !duplicate), but the sense may be reversed?
var pass = valid && unique; // A composite pass/fail boolean for this email element.
if(!pass) {
$(el).addClass('emailError');
} else {
$(el).removeClass('emailError');
}
// Note: It would be better to give the user separate indications of invalid|duplicate, so (s)he has a better clue as to what's wrong.
return pass; // whatever is returned here will be the value delivered by the promise inserted into the `promises` array
});
});
// Now use `$.when()` again to aggregate the `promises` array.
return $.when.apply(null, promises).then(function() {
// Now use `Array.prototype.reduce` to scan the arguments list (booleans) and give a composite pass/fail boolean.
var pass = Array.prototype.reduce.call(arguments, function(prev, current) {
return prev && current;
}, true);
if(!pass) {
return $.Deferred().reject(new Error(errmsg("At least one email is not valid."))).promise(); // jQuery's cumbersome way to `throw` an error from a promise chain.
}
});
}
调用如下:
this.newValidate($("#myForm")).then(function() {
// pass
}, function(error) {
// Something went wrong.
// Expected error or unexpected error will end up here.
consoe.log(error);
$("#whatever").append('<div class="error">' + error.message + '</div>'); // if required
});
我迷路了,不确定要查找什么。我知道这可能与 jQuery 承诺有关。所以,开门见山,我正在尝试 return 一个 "pass" 变量作为布尔值来检查电子邮件是否有效。它不是传递带有值 = "asdf" 的 false,而是传递 true。我知道这是因为异步请求,我只是不确定如何推迟该变量。代码如下:
console.log( this.newValidate($('#forgottenPwdForm'))); // Returns true
newValidate: function(form){
var $form = form,
errmsg = function(msg){
return '<span class="error" style="text-align:right; margin: 2px 15px; color:red;">' + msg + '</span><br/>';
};
// Check email / username
// Needs to run 2 validations. Is the email valid? And is it duplicate if valid
if($form.find('.email').length)
$form.find('.email').each(function(){
var email = escape($(this).val().trim()),
valid = true,
duplicate = false,
pass = true;
// Check if email is valid
$.when(
$.get('/service/account/ajaxdata?method=validemail&emailaddr='+email, function(res){
console.log(res);
valid = res;
}),
$.get('/subscribe/check_email?email=' + email, function(data) {
if(data){
duplicate = false; }
})
).then(function(){
if(valid == 0){
var error = errmsg("Email is not valid.");
pass = false;
console.log(pass);
}
else {
// Now that the email is valid, we need to check if it's duplicate
if(duplicate == false) {
$('.email').addClass('emailError');
pass = false;
}
else {
if($('.email').hasClass('emailError')) {
$('.email').removeClass('emailError');
$('.email').removeClass('error');
}
pass = true;
}
}
});
if(pass == false) return pass;
});
代码 return 为真,而应 return 为假。同样,我知道这与 $.get 请求和变量超出范围有关,我只是不确定如何推迟它。
您需要使用结果执行回调方法,而不是设置变量。
代码是 运行 异步的,因此执行会一直持续到最后而不执行任何验证代码,这就是为什么您总是得到 true 的原因。
所以不要说 pass = true|false 你需要做类似的事情:MyCallBackFunction(true|false)
在 newValidate()
中,您正在使用承诺,因此 return 承诺 。请不要试图传入回调“because then you lose exception bubbling (the point of promises) and make your code super verbose”(@Esailija)。
这是对 promises 的相当具有挑战性的介绍,因此有很多评论:
newValidate: function($form) {
var $emailElements = $form.find('.email');
var promises = $emailElements.map(function(index, el) { // Use `.map()` to produce an array of promises.
var email = escape($(el).val().trim());
return $.when(
$.get('/service/account/ajaxdata?method=validemail&emailaddr=' + email), // no direct callback here ...
$.get('/subscribe/check_email?email=' + email) // ... or here.
).then(function(valid, unique) { // Simple! The two $.get() responses appear hear as arguments.
// The question's `data` appears to be a `unique` indicator (ie !duplicate), but the sense may be reversed?
var pass = valid && unique; // A composite pass/fail boolean for this email element.
if(!pass) {
$(el).addClass('emailError');
} else {
$(el).removeClass('emailError');
}
// Note: It would be better to give the user separate indications of invalid|duplicate, so (s)he has a better clue as to what's wrong.
return pass; // whatever is returned here will be the value delivered by the promise inserted into the `promises` array
});
});
// Now use `$.when()` again to aggregate the `promises` array.
return $.when.apply(null, promises).then(function() {
// Now use `Array.prototype.reduce` to scan the arguments list (booleans) and give a composite pass/fail boolean.
var pass = Array.prototype.reduce.call(arguments, function(prev, current) {
return prev && current;
}, true);
if(!pass) {
return $.Deferred().reject(new Error(errmsg("At least one email is not valid."))).promise(); // jQuery's cumbersome way to `throw` an error from a promise chain.
}
});
}
调用如下:
this.newValidate($("#myForm")).then(function() {
// pass
}, function(error) {
// Something went wrong.
// Expected error or unexpected error will end up here.
consoe.log(error);
$("#whatever").append('<div class="error">' + error.message + '</div>'); // if required
});