I currently have some code using jQuery Deferred and ajax to call remote api and get the data and put in localStorage and get data from localStorage.
This code seems buggy the first time it runs (i.e. it doesn't render the data until browser refresh) but it works perfectly after that until the cache expires and same problem again the first time it runs.
I want to rewrite the code using promise to modernize the codebase as well as tackle the bug. I am pretty new to JS promises and I wonder if there is any other improvements that can be made?
var btCalendarOps = {
lifespan: 4*3600000, //4 hours = 8*3600000
def: $.Deferred(function(def){
if (localStorage && localStorage.getItem('btCalData')) {
def.resolve(JSON.parse(localStorage.getItem('btCalData')))
}
else {
def.resolve({});
}
}).promise(),
fetchData: function(){
if (localStorage && (!localStorage.getItem('btCalData')
|| !localStorage.getItem('btCalDataTimeSpan')
|| parseInt($.now(), 10) - parseInt(localStorage.getItem('btCalDataTimeSpan'), 10) > this.lifespan))
{
console.log("localStorage refreshed with fresh API data");
this.def = $.ajax({
url: url,
method: "GET",
dataType: 'json',
success: function (data) {
if (localStorage) {
localStorage.setItem('btCalData', JSON.stringify(data));
}
}
}).then(function(){
return JSON.parse(localStorage.getItem('btCalData'));
});
localStorage.setItem('btCalDataTimeSpan', $.now());
}
return this.def;
}
}
//current usage
btCalendarOps.fetchData().done(function (data) {
//render data as a list
});
My new version:
const btCalendarOps = {
lifespan: 4*3600000, //4 hours = 8*3600000
fetchData: function(){
const cache = localStorage && localStorage.getItem('btCalData')
&& localStorage.getItem('btCalDataTimeSpan')
&& parseInt($.now(), 10) - parseInt(localStorage.getItem('btCalDataTimeSpan'), 10) > this.lifespan
? localStorage.getItem('btCalData') : null;
// if the data is in the cache, return it.
if (cache){
return Promise.resolve(JSON.parse(cache));
}
// else get the data and store it.
return Promise.resolve(
fetch(url)
.then((res) => res.json())
.then((data) => {
localStorage && localStorage.setItem('btCalData', JSON.stringify(data));localStorage.setItem('btCalDataTimeSpan', $.now());
return data;
})
);
}
}
You could use an
asyncfunction:You should no longer use
done, butthen(orasyncandawait):