1

As in the title, I'm wondering how to send few asynchronous requests and, after they're processed, change a part of my website (in this instance a single counter). Doing it synchronous way gives just the outcome I expect to get, but it freezes the website for a quite a long time. My current code is as follows:

var twitchReq = new XMLHttpRequest;


        function twitchR(x,y)
            {
                var api_key = "some_api_key";
                var source = "https://api.twitch.tv/kraken/streams/" + y + "?&client_id=" + api_key + "&callback=";
                x.open("GET", source, false);
                x.send(null);
                var z = twitchPR();
                return z;
            }
        function twitchPR()
            {
                if(twitchReq.status == 200)
                        {
                            if(twitchReq.readyState == 4)
                                    {
                                        var a = twitchReq.responseText;
                                        var b = JSON.parse(a);
                                        var c = twitchD(b);
                                        return c;
                                    }
                        }
            }
        function twitchD(x)
            {
                if(x.stream == null)
                    {
                        console.log("Offline");

                        return 1;

                    }
                else 
                    {
                        console.log(x);

                        return 2;
                    }

            }
        function twitchWidget()
            {
               var t = [
                   "Nervarien",
                   "Jankos",
                   "LolVander",
                   "RossBoomsocks",
                   "ESL_LOL",
                   "Xayoo_",
                   "Kubon_"
               ]
                var j=0;
                var n=0;
                for(i=0;i<7;i++)
                        {


                            if(twitchR(twitchReq,t[i]) == 1)
                               {
                                    j=j+1;


                               }
                            else    
                                {
                                    n=n+1;


                                }


                        }
                document.getElementById("test-1").innerHTML = "Online: " + n + "<br>" + "Offline: " + j;
            }

I've figured out that the nail in the coffin of this solution is waiting for one request to be finished before sending another, not to mention freezing any other code in queue. So: how do i process the outcome of my request once they are finished and wait for the others to be finished at the same time?

EDIT: Regarding 'possible duplicate' mark - I've seen that thread and yet, I couldn't tell how to solve my problem. The difference is, he could just use ajax promises, while I had no idea how to make one, and therefore couldn't use solutions posted there.

  • Possible duplicate of [How can I wait for set of asynchronous callback functions?](http://stackoverflow.com/questions/10004112/how-can-i-wait-for-set-of-asynchronous-callback-functions) – Heretic Monkey Apr 19 '17 at 16:57

2 Answers2

0

I think you need http://caolan.github.io/async/ lib, They have a very good set of methods to accomplish parallel and series Ajax calls. Adding one lib for a single method is kind of quite expensive, but this way code is more organized and easy to maintain.

Santhanam
  • 348
  • 4
  • 15
0

There are several ways to do it. I will suggest here to use a promise for the HTTP request:

// Helper function to make Http request and return a promise
function promiseHttpData(source) {
    return new Promise(function (resolve, reject) {
        var req = new XMLHttpRequest;
        req.onload = resolve.bind(null, req);
        req.onerror = reject.bind(null, req);
        req.open("GET", source);
        req.send();
    });
}

function twitchR(y) {
    var api_key = "some_api_key";
    var source = "https://api.twitch.tv/kraken/streams/" + y 
                 + "?&client_id=" + api_key + "&callback=";
    return promiseHttpData(source).then(twitchPR);
}

function twitchPR(twitchReq) {
    var a = twitchReq.responseText;
    var b = JSON.parse(a);
    var c = twitchD(b);
    return c;
}

function twitchD(x) {
    if(x.stream == null) {
        console.log("Offline");
        return 0; // Use of zero is easier to work with
    } else {
        console.log(x);
        return 1;
    }
}

function twitchWidget() {
    var t = [
       "Nervarien",
       "Jankos",
       "LolVander",
       "RossBoomsocks",
       "ESL_LOL",
       "Xayoo_",
       "Kubon_"
    ]
    var promises = t.map(twitchR); //Launch request for each

    // Get the promised values for all promises:
    Promise.all(promises).then(function (values) {
        var n = values.filter(Number).length; // returns the number of non-zeroes.
        var j = t.length - n;
        document.getElementById("test-1").innerHTML = 
            "Online: " + n + "<br>" + "Offline: " + j;
    });
}
trincot
  • 317,000
  • 35
  • 244
  • 286
  • I used 1 and 2 since I was worried about return value 0 being some kind of control number of the browser, I'll check your solution soon. Thanks! EDIT: It seems to work fine, there is a missing "+" operator in function twitchR, no biggie tho. –  Apr 20 '17 at 10:04
  • Oops, I had deleted that `+` by accident. The 0 makes the `filter(Number)` work, otherwise (with values 1 and 2) you'd have to write `filter(x => x > 1)`. I like the first more. – trincot Apr 20 '17 at 12:01