Javascript,变量引用

时间:2009-08-13 18:35:03

标签: javascript function

在类似下面的代码的情况下,您将如何访问匿名函数中的变量值?我想返回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);
}

8 个答案:

答案 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请求处理程序更新隐藏元素中的数据。然后,您的轮询(我推测)查询函数可以查看隐藏元素以查看最终是否设置了“就绪”标志。