We know that for a Promise, there are the following features:

const promise = new Promise((resolve, reject) => { console.log('running'); setTimeout(() => { resolve('something out'); }, 1000); }); promise.then((result) => { console.log('first then:' + result); }); promise.then((result) => { console.log('second then:' + result); }); // Running // first then: something out // second then: something outCopy the code

A promise itself will resolve() only once, and its executor in New Promise(Executor) will execute only once. But you can call a promise’s then() method multiple times, whether it’s resolved or rejected.

That is, a Promise “remembers” its resolve or reject result, and whenever its THEN () is called, it returns the saved result to the then() callback.

The original implementation

Using this feature, we can imagine that if a front-end data request returns a promise, it is easy to implement data caching using this feature:

const button = document.getElementById('button'); let request; button.addEventListener('click', () => { if (! request) { request = axios.get('/get/something'); } request.then((result) => { alert(result); }); });Copy the code

Further refinement

Consider the following:

  • The same request may have different parameters each time, and I need to cache different results for different parameters
  • My cache must be fresh, and I need to re-request it if the cache lasts too long
  • If the first request fails, I should not cache the result of the failure
  • At some point I want to actively clear the cache

We can design an API that looks like this:

function memorize(fn, opts) { opts = { cacheKeyFn: defaultCacheKeyFn, maxAge: undefined, cache: {}, ... opts }; const memorized = function (... args) { // ... }; memorized.clear = function () { opts.cache = {}; }; return memorized; } const request = (userId, page){return axios.get(' /get/something/${userId}? page=${page}); }; Const memorizedRequest = memorize(request, {// expiration date 10s maxAge: 10 * 1000}); // Clear the cache memorizedRequest.clear();Copy the code

This completes a simple front-end cache library.