[removed] XHR not handling multiple async requests

2019-08-08 03:41发布

Hi I am trying to access one resource multiple times with with different parameters

In this case requesting

    var domains = [
    'host1',
    'host2'
    ];

    var requests = new Array();

    for ( i in domains )
    {
        requests[i]=new request(domains[i]);
    }

    function request(site)
    {
        var url = 'get_remote_status.php?host='+site;
        var queues = {};
        http_request = new XMLHttpRequest();
        http_request.open("GET", url, true, 'username', 'password');
        http_request.onreadystatechange = function () {
            var done = 4, ok = 200;
            if (http_request.readyState == done && http_request.status == ok) {
                queues = JSON.parse(http_request.responseText);
                var queuesDiv = document.getElementById('queues');
                print_queues(queues, queuesDiv, site);              
            }
        };
        http_request.send(null);
    }

However, only one of of the requests is being handled by the code lambda. Chromium reports that both requests have been received and is viewable in the resourced pane.

Also if I make the request synchronous then it works fine. However this is not acceptable to the release code as a request may timeout.

Thanks

2条回答
家丑人穷心不美
2楼-- · 2019-08-08 04:07

Define http_request using var. Currently, you're assigning the XHR object to a global variable. Because of this, your script can only handle one XHR at a time.

Relevant erroneous code:

function request(site)
{
    var url = 'get_remote_status.php?host='+site;
    var queues = {};
    http_request = new XMLHttpRequest();

Proposed change:

function request(site)
{
    var url = 'get_remote_status.php?host='+site;
    var queues = {};
    var http_request = new XMLHttpRequest(); //VAR VAR VAR !!!

When you omit var before a variable, the variable will be defined in the global (window) scope. If you use var before a variable, the variable is defined within the local scope (in function request, in this case).

查看更多
男人必须洒脱
3楼-- · 2019-08-08 04:13

In fact it is possible to run multiple async xhr call but you have to give them an unique id as parameter to be able to store and load them locally in your DOM.

For example, you'd like to loop on an array and make a ajax call for each object. It's a little bit tricky but this code works for me.

var xhrarray={};
for (var j=0; j<itemsvals.length; j++){
                var labelval=itemsvals[j];
                // call ajax list if present.
                if(typeof labelval.mkdajaxlink != 'undefined'){
                    var divlabelvalue = '<div id="' + labelval.mkdid + '_' +          item.mkdcck + '" class="mkditemvalue col-xs-12 ' + labelval.mkdclass + '"><div class="mkdlabel">' + labelval.mkdlabel + ' :</div><div id="'+ j +'_link_'+ labelval.mkdid +'" class="mkdvalue">'+labelval.mkdvalue+'</div></div>';
                    mkdwrapper.find('#' + item.mkdcck + ' .mkdinstadivbody').append(divlabelvalue);

                    xhrarray['xhr_'+item.mkdcck] = new XMLHttpRequest();
                    xhrarray['xhr_'+item.mkdcck].uniqueid=''+ j +'_link_'+ labelval.mkdid +'';
                    console.log(xhrarray['xhr_'+item.mkdcck].uniqueid);
                    xhrarray['xhr_'+item.mkdcck].open('POST', labelval.mkdajaxlink);
                    xhrarray['xhr_'+item.mkdcck].send();
                    console.log('data sent');
                    xhrarray['xhr_'+item.mkdcck].onreadystatechange=function() {
                        if (this.readyState == 4) {
                            console.log(''+this.uniqueid);
                            document.getElementById(''+this.uniqueid).innerHTML = this.responseText;
                        }
                    };
                }
}

You have to set each xhr object in a global variable object and define a value xhrarray['xhr_'+item.mkdcck].uniqueid to get its unique id and load its result where you want.

Hope that will help you in the future.

查看更多
登录 后发表回答