I often meet the pattern where I need to either retrieve data from cache or fetch it from the server (both applies as well). I tried to implement such data loading policy in a generic fashion, but I cannot found an ideal design for this purpose, so I decided to share it and let the JS community help me to improve it :)
In this project, I will use a DataLoader
class intended to implement this policy, fetching some data from 2 sources :
- Either from a backend (server)
- Or from localstorage (if a previous call to the backend was made "recently", "recently" corresponding to still having such data in memory)
I'd like to implement a single method utility allowing to address both data resolutions at the same time, afterall, we should consider this as a single promise which may be resolved multiple times :
- Only once if localstorage is empty (the first time we run the application)
- Only once if localstorage is filled and we already called the backend "recently"
- Twice if localstorage is filled and the backend was called some time ago, in that particular case, I'd like :
- To quickly return data coming from cache
- Run in the background an XHR to the server, and resolve the promise again once data is fetched (thus, in the case where backend is not reachable -for instance because user has connectivity issues-, user will still have presentations coming from cache)
I guess this is a very common pattern of "serve my data from the cache first, then try to refresh it from an http call"
Currently, I didn't achieved to find any library on the www, allowing to achieve this goal in a beautiful way.
My current implementation takes my callback (called potentially twice) as the loadEventsThen() method.
However, this doesn't look like a promise, and is then not composable at all : I cannot call loadEventsThen() in an async/promisified
call since callback may be called twice.
If you have any idea on how to improve this design, don't hesitate to share it, I would be happy to discuss this with you on this gist :-)
What I DO want is :
- Keep the way I call DataLoader : passing a unique callback which may be called everytime I'm able to access the data
- Improve this in order to make it more promise friendly
- Maybe refactor the whole thing if you think there is a design issue, but keep in mind that data may come from various locations (in my case, 3 locations : server, localstorage or memory) and everytime data is made available, I'd like to execute the exact same callback (in my case, display number of voxxrin events available)
@DavidBruant yes and maybe do something like :
My concern is ... my example is ratherly simple here since my data access layer is near my view ... in reality, there are some business logics between both ... and converting a promise-based code to event-based code is not that straightforward :'/