Conditions and Promises
Sometimes your asynchronous function calls another asynchronous function conditionally. Writing such code in an elegant way may take a bit of effort. Case in point: let's consider application logic, in which we cache response from an API call and therefore only make an API call if the information is stale or missing. An if
statement where part of it is calling asynchronous logic and part is not can get messy. Let's see an example code where we try to untangle the complexity.
Note: this is an example code for demonstration purposes-only, it is missing trivial parts for brevity and is therefore not runnable as-is:
const Promise = require('bluebird');
const rp = require('request-promise');
const fakepromise = require('fakepromise');
class SomeModel {
constructor() {
this.cachedEntity = {};
}
lookupValue() {
let waitForRefresh;
if (!this.isFresh()) {
console.log("Rereshing entity...")
waitForRefresh = this.refreshEntity();
} else {
console.log("Entity from cache...")
// Fake wait, creates a fulfilled promise:
waitForRefresh = Promise.resolve(this.cachedEntity);
}
return new Promise((resolve, reject) => {
waitForRefresh.then((response) => {
response = this.processResponse(response);
this.cachedEntity = response; // refresh cache
resolve(response);
}).catch((err) => {
reject(err);
});
})
}
isFresh() {
if (!this.cachedEntity.lastFresh) {
return false;
}
// or if older than 5 secs - consider not-fresh
if ((Date.now() - this.cachedEntity.lastFresh) > 5000) {
return false;
}
return true;
}
processResponse(response) {
response.processed = true;
return response;
}
refreshEntity() {
const retValue = {};
retValue.lastFresh = Date.now();
retValue.value = Math.random() * 700; // 0 - 700
return fakepromise.promise(200, retValue);
}
}
let model = new SomeModel();
model.lookupValue().then(response1 => {
console.log(response1);
return model.lookupValue();
}).then(response2 => {
console.log(response2)
});
Side note: source files of all examples and instructions for how to execute, are located at: https://github.com/inadarei/promises123-code
In summary, by introducing a variable that is assigned to the sub-call invoking a promise and turning non-async part of the if
logic into a fake promise, we can make code look uniform and clean. Which is what you see in the implementation of lookupValue() function. The refreshEntity() function implementation is not directly related to the trick we are explaining, but is included here to bring more clarity to the context of the discussion.
Last updated
Was this helpful?