Skip to content

Instantly share code, notes, and snippets.

@nathansmith
Last active December 28, 2023 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathansmith/760a7796d66167a2d96ec2beeb336909 to your computer and use it in GitHub Desktop.
Save nathansmith/760a7796d66167a2d96ec2beeb336909 to your computer and use it in GitHub Desktop.
🐶 Example of cached fetch promise

For work, I made an example of how to cache a fetch promise.

This is different than awaiting a promise and saving the result. Subsequent calls will use the same promise.

It outputs alternating logs:

  • Image object.

  • String "bad dog".

After the loop there is one more setTimeout call. But there is no extra fetch in the network traffic.

The magic is response.clone() whereas directly calling response.json() again would cause an error.

// ==============
// Promise cache.
// ==============
const dogPromiseList = new Map();
// ================
// Helper: get dog.
// ================
const getDog = async (dogId = '') => {
// Set later.
let dog;
// Promise exists: NO.
if (!dogPromiseList.has(dogId)) {
// Set later.
let dogPromise;
// Even ID: YES.
if (dogId % 2 === 0) {
// Get promise.
dogPromise = window.fetch('https://dog.ceo/api/breeds/image/random');
} else {
// Get promise.
dogPromise = Promise.reject('bad dog');
}
// Add to list.
dogPromiseList.set(dogId, dogPromise);
}
try {
// Get response.
let response = await dogPromiseList.get(dogId);
// Clone.
response = response.clone();
// Get JSON.
dog = await response.json();
} catch (error) {
// Log.
console.log(dogId, error);
// Clear.
dogPromiseList.delete(dogId);
}
// Expose object.
return dog;
};
// ==============
// Test our code.
// ==============
// Closure: START.
(async () => {
// Loop through.
for (let dogId = 0; dogId < 10; dogId++) {
// Get dog.
const dog = await getDog(dogId);
// Dog exists: YES.
if (dog) {
// Log.
console.log(dogId, dog);
}
}
// Set timer.
setTimeout(async () => {
/*
=====
NOTE:
=====
Call again, to check if we send
another `fetch` for the same ID.
*/
// Get ID.
const dogId = 0;
// Get dog.
const dog = await getDog(dogId);
// Dog exists: YES.
if (dog) {
// Log.
console.log(dogId, dog);
}
// Slight delay.
}, 2000);
// Closure: END.
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment