The normal synchronous way of doing things is nice and straightforward.
- A function takes in inputs.
- The function performs an action with those inputs.
- The function ejects out a value (returns a value).
- The value that is ejected can be stored into a variable, used directly in other parts of the synchronous code, etc.
But async doesn't seem to be able to do this.
Let's say that I have a service that I want to sell. The price of the service varies by location.
I have a user:
- Enter in a Zip Code
- Zip Code gets sent to an API while returns a city name.
- I use the city name to run a super huge function that returns a price.
- I then want to use the price in other parts of my synchronous code, and that synchronous code is super long and spans across numerous functions that all depend on the price value.
Code:
var calcPrice = function(city){
// stuff runs
return price;
};
// Async Function, taken from http://www.zippopotam.us/
// The "place name" is the city.
var returnLocationInfoByZip = function(zip, callback){
var client = new XMLHttpRequest();
var response;
client.open("GET", "http://api.zippopotam.us/us/" + zip, true);
client.onreadystatechange = function() {
if(client.readyState == 4) {
response = client.responseText;
callback(JSON.parse(response));
};
};
client.send();
};
var zip = "94043";
var price = returnLocationInfoByZip(zip, function(response){
calcPrice(response.places[0]["place name"]);
});
// This does not work. I'm going to call this the "dependent processing" part of my code.
functionThatDependsOnPrice(price);
AnotherFunctionThatDependsOnPrice(price);
MoreFunctionsThatDependsOnPrice(price);
EvenMoreFunctionsThatDependOnPrice(price);
// This I THINK would work instead
returnLocationInfoByZip(zip, function(response){
price = calcPrice( response.places[0]["place name"] );
functionThatDependsOnPrice(price);
AnotherFunctionThatDependsOnPrice(price);
MoreFunctionsThatDependsOnPrice(price);
EvenMoreFunctionsThatDependOnPrice(price);
});
Stuffing all of that code in the callback is really really ugly and confusing.
I would like to just use the price variable inside of my normal synchronous code. But the value from calcPrice
never gets returned and thus never gets stored into the price variable. The value of calcPrice
is forever stuck inside the asynchronous branch of my code flow which forces me to do all my other dependent processing inside the asynchronous branch / callback.
So a few questions:
Is it correct that asynchronous code is never able to return a value back into the synchronous code? The normal synchronous way of doing and thinking about things just won't work.
Is a fat callback pretty much normal?
I could go the Promise route, but if I do that I'm just stuffing all of the dependent processing into my then
function... it's a little cleaner looking but it's still nested deep inside other things.