NodeJS Cache - Retrieve data and push to array

Not applicable

Hi,

My requirement is to retrieve data from cache and populate an array in NodeJS...I have used apigee-access module to create and populate the cache.

But for some reason my array is empty when printed outside the callback

Code Snippet

var cacheResp = [];
cache.get(cacheKey,function(err, data) {
  cacheResp.push(data);
  console.log("**** Cache 1: **** " + cacheResp);
}); 
console.log("**** Cache 2: **** " + cacheResp);

In the output I see log Cache 1 with contents of CacheResp array but Cache2 is empty..
Can you please help
0 3 4,939
3 REPLIES 3

Yes! I can help. Thanks for the code.

Here's what's happening.

The cache.get() is asynchronous. What that means is, it returns *immediately*. The callback function gets called *later*. Let's walk through it.

Your code is like this:

var cacheResp = [];
cache.get(cacheKey,function(err, data) {
  cacheResp.push(data);
  console.log("**** Cache 1: **** " + cacheResp);
}); 
console.log("**** Cache 2: **** " + cacheResp);

By using a named function for the callback, we could rewrite it to this:

/* 1 */ var cacheResp = [];
/* 2 */ function callback(err, data) {
/* 3 */   cacheResp.push(data);
/* 4 */   console.log("**** Cache 1: **** " + cacheResp); // something good
/* 5 */ }
/* 6 */ 
/* 7 */ cache.get(cacheKey,callback); 
/* 8 */ console.log("**** Cache 2: **** " + cacheResp); // empty

In the above (modified) code, lines 1-6 get executed. The effect of lines 2-5 is to define a function. The function does not yet execute. The amount of time required to execute lines 1-6 is.... less than 1 millisecond. Much less. It's just doing in-memory things in JavaScript.

Then line 7 runs. The cache.get results in a network call. This network call is sending out a request to a remote system. You may wonder, Which remote system? Where is the remote system? That's not important right now. The important thing to know is that because there is a callback function, the results of the cache.get() will be sent back via a callback. This pattern is known as asynchronous JavaScript. So, the cache.get() kicks off some work, and ... then....returns! Pretty quickly. Again, within less than 1 millisecond. At this point, line 7 has executed in its entirety. There is some invisible magic (it's not important to understand what/how) that will trigger the callback ~later~ , but line 7 is done. Then line 8 runs. Because the callback has not yet been invoked, the cacheResp has not yet been set! So you see an empty cache.

Then, after the network call returns, probably 10-50ms later, the invisible magic calls the callback function. The callback function runs, and lines 3 and 4 execute. Finally, the cacheResp has been set. But that is long after line 8 has executed.

This is basic asynchronous JavaScript. I looked around and found a more complete introduction to the concept. Find it here.

To work around this problem you need to refactor your code to consider the asynchronous nature of the cache.get. Without further context around the problem you're confronting, I can't help you further.

Thanks for taking the time to explain in such details...Got the clarity of the problem..

My usecase is to store the responses from the target (making multiple call parallel using NodeJS) in the cache and next time when a request is made check if the details are already there in the cache and return that in the response...

Im using Node JS to make parallel calls to the backend and hence need to check for the value in cache looping through the request...henceforth trying to push all the responses found in the cache to the array and use that as a response to return..

Thanks

ok, so it sounds as though you have a standard cache concurrency issue to confront. You'll need to decide how to populate the cache and whether to defer network requests while cache updates are pending. Good stuff. I guess you have the tools and understanding now, to solve the problem. Good luck!