不调用XMLHttpRequest onload

时间:2018-08-16 16:08:47

标签: javascript post get xmlhttprequest

我是JS的新手。 据我了解,在函数XMLHttpRequest中创建的createNewGetXHR()的新实例必须在发送请求后触发onload回调函数。现在,它无需触发回调即可工作。但是,如果我在postData()回调中注释了do-while循环(字符串55和63),则开始工作(如何在循环中创建新的GET请求,以便可以控制此循环的退出?

    <script>
        function sleep(ms) {
            ms += new Date().getTime();
            while (new Date() < ms){}
        }
        function createNewGetXHR(uniqId, server_state) {
            alert("In createNewGetXHR()");
            var url = "http://localhost:8080/api/users?uniqId=" + uniqId;
            var xhr = new XMLHttpRequest();

            xhr.open("GET", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onload = function () {
                alert("Fired onload callback");
                if (xhr.readyState === xhr.DONE) {
                    if (xhr.status === 200) {
                        var server_resp = xhr.responseText;

                        alert("server_resp: " + server_resp);
                        if (server_resp !== "-") {
                            server_state.working = false;
                            server_state.response_html = server_resp;
                        }
                    }
                }
            };

            return xhr;
        }
        function postData() {
            // Get data from froms
            var name = document.getElementById('name').value;
            var surname = document.getElementById('surname').value;
            var action = document.getElementById('action').value;
            // Make json from data
            var data = JSON.stringify({"action": action, "user": {"name": name, "surname": surname}});
            // Prepare request
            var url = "http://localhost:8080/api/users";
            var xhr = new XMLHttpRequest();

            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            // Handle server response
            xhr.onload = function () {
                if (xhr.readyState === xhr.DONE) {
                    if (xhr.status === 200) {
                        alert("Server is working. Please wait for the answer!");

                        var REFRESH_RATE = 2000;
                        var uniqId = xhr.responseText;
                        var server_state = { working: true, response_html: "default" };
                        var reqs_holder = [];

                        // Checking for the server answer every $REFRESH_RATE
                        do { // (1) if comment out it - code start working(once)
                            sleep(REFRESH_RATE);

                            var new_req = createNewGetXHR(uniqId, server_state);

                            reqs_holder.push(new_req);
                            new_req.send();
                            //alert("Send GET");
                        } while (server_state.working); // (2) if comment out it - code start working(once)

                        document.write(result_html);
                    }
                }
            };
            // Make post request
            xhr.send(data);
        }
    </script>

1 个答案:

答案 0 :(得分:0)

据我了解,虽然代码在循环内旋转,但未执行诸如onload之类的回调。由于循环的退出条件是在回调内部设置的,因此我们得到了无限循环。解决方案是尾部递归函数,如果服务器仍未处理请求,则会在延迟后调用自身。

    <script>
        function sleep(ms) {
            ms += new Date().getTime();
            while (new Date() < ms){}
        }
        function waitForResponse(uniqId, refresh_rate) {
            var url = "http://localhost:8080/api/users?uniqId=" + uniqId;
            var xhr = new XMLHttpRequest();

            xhr.open("GET", url, false);
            xhr.onload = function () {
                if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                    var server_resp = xhr.responseText;

                    if (server_resp === "-") {
                        sleep(refresh_rate);
                        waitForResponse(uniqId, refresh_rate);
                    }
                    else
                        document.write(server_resp);
                }
            };
            xhr.send();
        }
        function postData() {
            /* Get data from froms the forms */
            var name = document.getElementById('name').value;
            var surname = document.getElementById('surname').value;
            var action = document.getElementById('action').value;
            var data = JSON.stringify({"action": action,
                "user": {"name": name, "surname": surname}}); // make json from data

            /* Prepare request */
            var url = "http://localhost:8080/api/users";
            var xhr = new XMLHttpRequest();

            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onload = function () { // handle server response
                if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                    alert("Server is working. Please wait for the answer!");

                    var REFRESH_RATE = 1000;
                    var uniqId = xhr.responseText;

                    waitForResponse(uniqId, REFRESH_RATE);
                }
            };
            xhr.send(data); // make post request
        }
    </script>