StrikeAgainst
StrikeAgainst

Reputation: 634

Is there a way to block my JS code until the XMLHttpRequest response arrives?

I'm trying to import some data through a PHP file with this function:

sendJsonRequest("initial", startID);
json = JSON.parse(request);

function sendJsonRequest(type, id) {
    if (window.XMLHttpRequest) {
        var xmlhttp = new XMLHttpRequest();
    } else {
        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            request = xmlhttp.responseText; //writing the response in an already defined variable
        }
    }
    xmlhttp.open("GET","../RequestHandler.php?"+type+"_"+id,true);
    xmlhttp.send();
}

The import of the data works very well. My problem now is that I want to use my request right after calling this function, to which point it's still not available (I realized this happens because onreadystatechange runs as function independently), therefore I have to put in some delay until it is so. I find the use of setTimeout or setInterval very uncomfortable, since those aren't blocking the code and I had to refactor some of my code very badly and inefficient. That's why I was looking for a way to modify/block out the function at its end, until the request is available, but neither using an empty while-loop nor the wait/pause/sleep-functions are recommended. Can anybody figure out another way to accomplish this?

Upvotes: 0

Views: 1737

Answers (2)

guest271314
guest271314

Reputation: 1

Try utilizing Promise

var sendJsonRequest = function sendJsonRequest(type, id) {
  return new Promise(function (resolve, reject) {
    if (window.XMLHttpRequest) {
        var xmlhttp = new XMLHttpRequest();
    } else {
        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            request = xmlhttp.responseText; 
            resolve(request);
        }
    }
    xmlhttp.error = reject;
    xmlhttp.open("GET","../RequestHandler.php?"+type+"_"+id,true);
    xmlhttp.send();
}

sendJsonRequest("initial", startID)
.then(function(data) {
  // do stuff
  var json = JSON.parse(data);
  console.log(json);
}, function err(e) {
  console.log(e);
});

Upvotes: 0

Mark Olsen
Mark Olsen

Reputation: 959

Could you just pass a callback?

function sendJsonRequest(type, id, callback) {
    if (window.XMLHttpRequest) {
        var xmlhttp = new XMLHttpRequest();
    } else {
        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            request = xmlhttp.responseText; //writing the response in an already defined variable

            if(callback) {
                callback(request);
            }  
        }
    }
   xmlhttp.open("GET","../RequestHandler.php?"+type+"_"+id,true);
   xmlhttp.send();
}

and use it like:

sendJsonRequest("initial", startId, function(req) {
    var json = JSON.parse(req);
});

Upvotes: 1

Related Questions