在类似下面的代码的情况下,您将如何访问匿名函数中的变量值?我想返回filterData的bool值(xmlhttp.responseText,thisForm);这将是主checkAvailable函数的布尔值。提前谢谢。
function checkAvailable(thisForm) {
var xmlhttp = httpRequest();
var isValid = true;
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.onreadystatechange = function(isValid) {
if (xmlhttp.readyState == 4) {
//I WANT TO ACCESS THIS isValid VARIABLE FROM MAIN FUNCTION checkAvailable
isValid = filterData(xmlhttp.responseText, thisForm);
}
}
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",true);
xmlhttp.send(null);
return isValid;
}
我现在的方式
function validateRegForm(thisForm) {
var isValid = true;
var warningIcon = "";//for later in case we want to use an icon next to warning msg
checkAvailable(thisForm, function(isValid) { });
if(isValid == false)
window.scroll(0,0);
alert(isValid);
return false;//isValidForm;
}
function checkAvailable(thisForm, resultFunction) {
var xmlhttp = httpRequest();
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.onreadystatechange = function(isValid) {
if(xmlhttp.readyState == 4) {
isValid = filterData(xmlhttp.responseText, thisForm);
resultFunction(isValid);
}
}
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",true);
xmlhttp.send(null);
}
答案 0 :(得分:5)
修改checkAvailable函数以获取一个附加参数,该参数是用结果调用的函数。
function checkAvailable(thisForm, resultFunction) {
..
xmlhttp.onreadystatechange = function(isValid) {
if (xmlhttp.readyState == 4) {
//I WANT TO ACCESS THIS isValid VARIABLE FROM MAIN FUNCTION checkAvailable
isValid = filterData(xmlhttp.responseText, thisForm);
resultFunction(isValid);
}
}
}
然后,您可以这样称呼它:
checkAvailable(thisForm, function(isValid) {
// Use the isValid value which is the result of the checkAvailable call.
});
修改强> 以下是对您发布的修改后代码的更改。
function validateRegForm(thisForm) {
var isValid = true;
var warningIcon = "";//for later in case we want to use an icon next to warning msg
checkAvailable(thisForm, function(isValid) {
if(isValid == false)
window.scroll(0,0);
alert(isValid);
}
// WARNING!! This will happen before the result is discovered.
// You'll need to modify the function that called into validateRegForm.
// It should not wait for a return parameter either.
return false;//isValidForm;
}
答案 1 :(得分:1)
你需要使你的XmlHttpRequest同步,你可以通过将.open()的最后一个参数设置为false来实现,即
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",false);
但是,这会在通话期间锁定您的UI / SJS
答案 2 :(得分:1)
一般而言,从匿名函数返回值的方法是利用Javascript的词法作用域性质。为此,您需要在与匿名函数相同的范围内声明一个变量,并让函数在执行期间设置变量。
例如:
function a() {
var x = 1;
(function() { x = 2; })();
alert(x); // x will be 2
}
然而,这完全取决于执行是线性的,这意味着在执行匿名函数之后发生警报。在上面提到的代码中,这不会发生,因为XMLHttpRequest是异步的,这意味着将在其他某个时间点调用onreadystatechange回调。您可以将XMLHttpRequest更改为同步,但这会在请求进行时锁定页面的UI。
function checkAvailable(thisForm) {
var xmlhttp = httpRequest();
var isValid = true;
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",false);
xmlhttp.send(null);
isValid = filterData(xmlhttp.responseText, thisForm);
return isValid;
}
处理这种情况的最佳方法是转移到完全异步的模型。在此模型中,将对checkAvailble()函数进行重构,以便在确定有效性后调用它。下面是一个示例:
function whenAvailable(theForm, callback) {
var xmlhttp = httpRequest();
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
if (callback) {
var isValid = filterData(xmlhttp.responseText, thisForm);
callback.call(null, isValid);
}
}
}
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",true);
xmlhttp.send(null);
}
对此功能的调用如下所示:
whenAvailable(document.getElementById('someForm'), function(valid) {
if (valid) {
// do something when valid
} else {
// do soemthing when invalid
}
});
答案 3 :(得分:0)
如果您需要等待响应继续,请使用SJAX(同步javascript和xml)来获取结果。在收到回复之前,您的脚本将不会继续。请注意,即。
中的超时错误处理不当另一方面,您可以使用AJAX并在readyState检查中执行您需要执行的操作,而不是尝试返回其他值来处理它。
答案 4 :(得分:0)
您需要将false
作为第三个参数传递给xmlhttp.open()
。这将导致请求同步执行,程序执行将暂停直到完成。
如果这样做,您将不需要匿名功能。你可以直接获得xmlhttp.responseText
:
function checkAvailable(thisForm) {
var xmlhttp = httpRequest();
var isValid = true;
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.open("GET", your_parameters, false);
xmlhttp.send(null);
isValid = filterData(xmlhttp.responseText, thisForm);
return isValid;
}
这样做的主要缺点是浏览器基本上会冻结,直到xmlhttp.send()
调用完成。
如果您可以重构代码以便不需要同步调用,那将是更好的IMO。
答案 5 :(得分:0)
在函数外创建一个对象...
obj = new Object;
obj.isValid = false;
obj.complete = false;
然后你的代码......除了
obj.isValid = filterData(xmlhttp.responseText, thisForm);
objt.complete = true;
确保对象定义位于函数上方,以使其显示为全局。
现在在另一方面你可以检测到状态4是否已经实现,如果有,那么你可以获取对象值。
您可能还需要在函数decalarion中传递对象,它应该通过ref和update传递它。
答案 6 :(得分:0)
你在范围函数中访问它的方式很好,问题是你想要做的事情不会像你期望的那样工作。正如其他人所提到的,你可以使用同步请求,但这可能不是你真正想要的(因为它会挂起你的UI)。
查看您的代码,我假设您有一个函数需要知道您的请求是否成功,然后继续处理。因此,您需要使用可以执行ajax请求的一次完成的回调,而不是使用标志。如下所示:
function checkAvailable(thisForm,callback){
var xmlhttp = httpRequest();
var isValid = true;
var un = document.getElementById('u_username').value;
var email = document.getElementById('u_email').value;
xmlhttp.onreadystatechange = function(isValid) {
if (xmlhttp.readyState == 4) {
//I WANT TO ACCESS THIS isValid VARIABLE FROM MAIN FUNCTION checkAvailable
isValid = filterData(xmlhttp.responseText, thisForm);
}
callback(isValid);
}
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+un+"&email="+email+"",true);
xmlhttp.send(null);
}
答案 7 :(得分:-1)
作弊:让ajax请求处理程序更新隐藏元素中的数据。然后,您的轮询(我推测)查询函数可以查看隐藏元素以查看最终是否设置了“就绪”标志。