Suppose I have a web application returning exchange rate for given currency pair at /exchange_rate/ccy1/ccy2, whenever the currency pair is not found in the database, the web app returns 404.
In the front-end JavaScript code, to be fail-safe, whenever local exchange rate query fails, I'll then query a public provider, say currencyconverterapi.com
Let's also assume for some reason (the actual code uses Vue lifecycle hooks), the global variable rate, and the two functions can't be merged and can't be made into async.
The problem with the following code is it only works when local query axios.get('/exchange_rate/EUR/' + ccy) resolves; when it rejects, the amount * rate will execute before axios.get('http://free.currencyconverterapi.com...) sets rate --
var rate;
function getExchangeRate(ccy) {
return axios.get('/exchange_rate/EUR/' + ccy)
.then(ret => {
rate = ret.data.rate;
}).catch(err => {
axios.get('http://free.currencyconverterapi.com/api/v5/convert?q=EUR_'
+ ccy).then(ret => {
rate = ret.data.results.val;
});
});
}
function toEUR(ccy, amount) {
getExchangeRate(ccy)
.then(() => {
return amount * rate;
});
}
var EURAmount = toEUR('USD', 42);
My question is: is there a way to guarantee rate is properly set by getExchangeRate in toEUR?
toEUR()doesn't return your promise. There are a few bad practices in your code, e.g. nesting a promise in another promise, and using a global updated asynchronously. The two functions don't need to be merged, just chained properly with.then().toEURcheck ifrate===undefined, and return an empty value if so. Assuming toEUR is a Vue computed value, andrateis a data field on the component, it'll automatically run again whenratechanges.toEUR-return getExchangeRate(ccy)...