Run code when group of ajax requests finish

时间:2015-07-08 15:49:52

标签: javascript ajax

I made a basic method that handles ajax, but I am not sure how to watch for when a group of requests (not necessarily all the ajax requests on the page) are complete so I can run additional code.

Here is the method:

request: function(options, success){
    var xmlhttp;
    var url = typeof options === "string" ? options : options.url;
    if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    }else{// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
            success(xmlhttp.responseText);
        }
    };
    var base = document.querySelector("base") || {href: "/"};
    xmlhttp.open("GET", base.href + ("/" + url).replace("//", "/"));
    xmlhttp.send();
    return this;
}

I am thinking I would like something like this to watch:

var requests = [];

for(var i = 0; i < 5; i++){
    requests.push(obj.request(url[i]));
}

// This one doesn't matter:
obj.request("/some/other/request.json");

// complete() is what would handle the items
requests.complete(function(data){
    // Run code when all requests finish
});

Is something like the possible and how? I would like to keep away from 3rd party libraries if possible.

I think my method needs to return a Promise instead but I am not sure...

2 个答案:

答案 0 :(得分:0)

Make your obj track all AJAX requests it receives, and let it track how many requests are complete.

You can do something really simple with

count: 0,
responses : [],
request: function(options, success){
    this.count++;
    ... etc etc

So count stores the number of active requests, and then

xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
        this.count--;
        this.responses.push(xmlhttp.responseText);
        if (this.count == 0)
            // execute all responses
    }
};

答案 1 :(得分:-1)

If your aim is to have multiple requests that are made and handled by a response callback, and then once all requests are complete call a complete call back function.

Then, you need to have a list of request objects each with a handler, and then a request manager that will take the requests execute them and maintain a count of outstanding requests and and check if the count is zero after each response and call the complete callback if remaining is 0.

function RequestManager(complete)
{
    this.count = 0;
    this.responses = [];
    this.complete = complete;
}

RequestManager.prototype.addRequest = function(options, base)
{
    this.count++;
    var thisObj = this;
    var xmlhttp;
    var url = typeof options === "string" ? options : options.url;
    if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    }else{// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
            thisObj.responses.push(xmlhttp.responseText);
                        thisObj.count--;
                        if(thisObj.count == 0)
                        thisObj.complete(thisObj.responses);
        }
    };
    xmlhttp.open("GET", base.href + ("/" + url).replace("//", "/"));
    xmlhttp.send();
}

var requestManager = new RequestManager(function(responses){
    console.log(responses);
});

var url = ['test2.html', 'test2.html', 'test2.html'];

for(var i = 0; i < 3; i++){
    requestManager.addRequest(url[i], { href: 'http://localhost' });
}