Присвоение функции javascript с параметрами переменной немедленно вызывается - PullRequest
0 голосов
/ 26 января 2012

Я пытаюсь сделать 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 ]

2 голосов
/ 26 января 2012

Он вызывается мгновенно , потому что вы называете его сразу после его определения:

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

Вам просто нужно:

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

Это создает замыкание вокруг объектов xmlHttp и func, что позволяет использовать их в функции при возникновении onreadystate даже после завершения функции post.

2 голосов
/ 26 января 2012
xmlHttp.onreadystatechange = function () {
    if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        func(xmlHttp.responseText);
    }
};

Не выполнять функцию вообще. Вы назначаете слушателя, т. Е. Создаете (не выполняете) функцию, которую будет вызываться в соответствующее время.

Значения внутри функции будут находиться в области видимости, поэтому нет необходимости передавать их (что не помогло бы, потому что даже делегирование не будет передавать их в любом случае). Это называется лексической областью, или статической областью, или функциональной областью (эти термины не идентичны, но в этом контексте они достаточно похожи).

1 голос
/ 26 января 2012

onreadystatechange является обратным вызовом и не должен выполняться самостоятельно.Это должно работать:

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