将带有参数的javascript函数分配给变量即可立即调用

时间:2012-01-26 18:30:38

标签: javascript function xmlhttprequest anonymous-function

我正在尝试在页面主体加载之前创建xmlHttpRequest。在尝试分配onreadystatechange函数时,此函数会立即调用 ,从而将xmlHttp.readyState 始终返回0

我打扰我以错误的方式打电话。我该如何正确分配功能?

//create xmlHttp object
function CreateXmlHttp() {
    try {
        var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
        try {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch(eo) {
            xmlHttp = null;
        }
    }
    if(!xmlHttp && typeof XMLHttpRequest != "undefined") {
        xmlHttp = new XMLHttpRequest();
    }
    return xmlHttp;
}

//request call
function post(url, func, XML) {
    var xmlHttp = CreateXmlHttp();
    //problem?
    xmlHttp.onreadystatechange = (function (xmlHttp, func) {
        if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
            func(xmlHttp.responseText);
        }
    })(xmlHttp, func);
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
    if(XML==null){
        XML = '';
    }
    xmlHttp.send(XML);
}

post('/json/checklogged', function (data) {
    var jsonData = eval("(" + data + ")"); //I know, this eval is dangerous
    if(jsonData.logged){
        var url = '${nextUrl}';
        post(url, function(data){
            document.open();
            document.write(data);
            document.close();
        });
        history.pushState({}, '', url);
    }
});

3 个答案:

答案 0 :(得分:2)

xmlHttp.onreadystatechange = function () {
    if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        func(xmlHttp.responseText);
    }
};

根本不执行该功能。您正在分配一个监听器,即创建(不执行)在适当的时间调用 的功能。

函数内部的值将在范围内,因此不需要传递它们(这没有用,因为偶数委托也不会传递它们)。它被称为词法范围,或静态范围,或功能范围(这些术语不相同,但在这种情况下它们足够相似)。

答案 1 :(得分:2)

它会被立即调用,因为你在定义后立即调用它

xmlHttp.onreadystatechange = (function (xmlHttp, func) {
    ...
})(xmlHttp, func);
  ^^^^^^^^^^^^^^^

你只需要:

xmlHttp.onreadystatechange = function () {
    if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        func(xmlHttp.responseText);
    }
};

这会在xmlHttpfunc对象周围创建一个闭包,允许您在onreadystate发生时在函数中使用它们,即使在post函数完成后也是如此。

答案 2 :(得分:1)

onreadystatechange是一个回调,不应该是自行执行的。这应该有效:

xmlHttp.onreadystatechange = function () {
        if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
            func(xmlHttp.responseText);
        }
};