Quantcast
Channel: How do I return the response from an asynchronous call? - Stack Overflow
Viewing all articles
Browse latest Browse all 46

Answer by loretoparisi for How do I return the response from an asynchronous call?

$
0
0

The following example I have written shows how to

  • Handle asynchronous HTTP calls;
  • Wait for response from each API call;
  • Use Promise pattern;
  • Use Promise.all pattern to join multiple HTTP calls;

This working example is self-contained. It will define a simple request object that uses the window XMLHttpRequest object to make calls. It will define a simple function to wait for a bunch of promises to be completed.

Context. The example is querying the Spotify Web API endpoint in order to search for playlist objects for a given set of query strings:

["search?type=playlist&q=%22doom%20metal%22","search?type=playlist&q=Adele"]

For each item, a new Promise will fire a block - ExecutionBlock, parse the result, schedule a new set of promises based on the result array, that is a list of Spotify user objects and execute the new HTTP call within the ExecutionProfileBlock asynchronously.

You can then see a nested Promise structure, that lets you spawn multiple and completely asynchronous nested HTTP calls, and join the results from each subset of calls through Promise.all.

NOTERecent Spotify search APIs will require an access token to be specified in the request headers:

-H "Authorization: Bearer {your access token}"

So, you to run the following example you need to put your access token in the request headers:

var spotifyAccessToken = "YourSpotifyAccessToken";var console = {    log: function(s) {        document.getElementById("console").innerHTML += s +"<br/>"    }}// Simple XMLHttpRequest// based on https://davidwalsh.name/xmlhttprequestSimpleRequest = {    call: function(what, response) {        var request;        if (window.XMLHttpRequest) { // Mozilla, Safari, ...            request = new XMLHttpRequest();        } else if (window.ActiveXObject) { // Internet Explorer            try {                request = new ActiveXObject('Msxml2.XMLHTTP');            }            catch (e) {                try {                  request = new ActiveXObject('Microsoft.XMLHTTP');                } catch (e) {}            }        }        // State changes        request.onreadystatechange = function() {            if (request.readyState === 4) { // Done                if (request.status === 200) { // Complete                    response(request.responseText)                }                else                    response();            }        }        request.open('GET', what, true);        request.setRequestHeader("Authorization", "Bearer "+ spotifyAccessToken);        request.send(null);    }}//PromiseAllvar promiseAll = function(items, block, done, fail) {    var self = this;    var promises = [],                   index = 0;    items.forEach(function(item) {        promises.push(function(item, i) {            return new Promise(function(resolve, reject) {                if (block) {                    block.apply(this, [item, index, resolve, reject]);                }            });        }(item, ++index))    });    Promise.all(promises).then(function AcceptHandler(results) {        if (done) done(results);    }, function ErrorHandler(error) {        if (fail) fail(error);    });}; //promiseAll// LP: deferred execution blockvar ExecutionBlock = function(item, index, resolve, reject) {    var url = "https://api.spotify.com/v1/"    url += item;    console.log( url )    SimpleRequest.call(url, function(result) {        if (result) {            var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) {                return item.owner.href;            })            resolve(profileUrls);        }        else {            reject(new Error("call error"));        }    })}arr = ["search?type=playlist&q=%22doom%20metal%22","search?type=playlist&q=Adele"]promiseAll(arr, function(item, index, resolve, reject) {    console.log("Making request ["+ index +"]")    ExecutionBlock(item, index, resolve, reject);}, function(results) { // Aggregated results    console.log("All profiles received "+ results.length);    //console.log(JSON.stringify(results[0], null, 2));    ///// promiseall again    var ExecutionProfileBlock = function(item, index, resolve, reject) {        SimpleRequest.call(item, function(result) {            if (result) {                var obj = JSON.parse(result);                resolve({                    name: obj.display_name,                    followers: obj.followers.total,                    url: obj.href                });            } //result        })    } //ExecutionProfileBlock    promiseAll(results[0], function(item, index, resolve, reject) {        //console.log("Making request ["+ index +"] "+ item)        ExecutionProfileBlock(item, index, resolve, reject);    }, function(results) { // aggregated results        console.log("All response received "+ results.length);        console.log(JSON.stringify(results, null, 2));    }    , function(error) { // Error        console.log(error);    })    /////  },  function(error) { // Error      console.log(error);  });
<div id="console" />

I have extensively discussed this solution here.


Viewing all articles
Browse latest Browse all 46

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>