diff --git a/src/__tests__/dataloader.test.js b/src/__tests__/dataloader.test.js index ddd2af8..7df7293 100644 --- a/src/__tests__/dataloader.test.js +++ b/src/__tests__/dataloader.test.js @@ -542,6 +542,19 @@ describe('Accepts options', () => { ]); }); + it('Does not interact with a cache when cache is disabled', () => { + const promiseX = Promise.resolve('X'); + const cacheMap = new Map([ [ 'X', promiseX ] ]); + const [ identityLoader ] = idLoader({ cache: false, cacheMap }); + + identityLoader.prime('A', 'A'); + expect(cacheMap.get('A')).toBe(undefined); + identityLoader.clear('X'); + expect(cacheMap.get('X')).toBe(promiseX); + identityLoader.clearAll(); + expect(cacheMap.get('X')).toBe(promiseX); + }); + it('Complex cache behavior via clearAll()', async () => { // This loader clears its cache as soon as a batch function is dispatched. const loadCalls = []; diff --git a/src/index.js b/src/index.js index 10e0d8b..c12525f 100644 --- a/src/index.js +++ b/src/index.js @@ -60,7 +60,7 @@ class DataLoader { // Private _batchLoadFn: BatchLoadFn; _options: ?Options; - _promiseCache: CacheMap>; + _promiseCache: ?CacheMap>; _queue: LoaderQueue; /** @@ -77,12 +77,12 @@ class DataLoader { // Determine options var options = this._options; var shouldBatch = !options || options.batch !== false; - var shouldCache = !options || options.cache !== false; + var cache = this._promiseCache; var cacheKey = getCacheKey(options, key); // If caching and there is a cache-hit, return cached Promise. - if (shouldCache) { - var cachedPromise = this._promiseCache.get(cacheKey); + if (cache) { + var cachedPromise = cache.get(cacheKey); if (cachedPromise) { return cachedPromise; } @@ -108,8 +108,8 @@ class DataLoader { }); // If caching, cache this promise. - if (shouldCache) { - this._promiseCache.set(cacheKey, promise); + if (cache) { + cache.set(cacheKey, promise); } return promise; @@ -148,8 +148,11 @@ class DataLoader { * method chaining. */ clear(key: K): this { - var cacheKey = getCacheKey(this._options, key); - this._promiseCache.delete(cacheKey); + var cache = this._promiseCache; + if (cache) { + var cacheKey = getCacheKey(this._options, key); + cache.delete(cacheKey); + } return this; } @@ -159,7 +162,10 @@ class DataLoader { * method chaining. */ clearAll(): this { - this._promiseCache.clear(); + var cache = this._promiseCache; + if (cache) { + cache.clear(); + } return this; } @@ -168,19 +174,21 @@ class DataLoader { * exists, no change is made. Returns itself for method chaining. */ prime(key: K, value: V): this { - var cacheKey = getCacheKey(this._options, key); - - // Only add the key if it does not already exist. - if (this._promiseCache.get(cacheKey) === undefined) { - // Cache a rejected promise if the value is an Error, in order to match - // the behavior of load(key). - var promise = value instanceof Error ? - Promise.reject(value) : - Promise.resolve(value); - - this._promiseCache.set(cacheKey, promise); + var cache = this._promiseCache; + if (cache) { + var cacheKey = getCacheKey(this._options, key); + + // Only add the key if it does not already exist. + if (cache.get(cacheKey) === undefined) { + // Cache a rejected promise if the value is an Error, in order to match + // the behavior of load(key). + var promise = value instanceof Error ? + Promise.reject(value) : + Promise.resolve(value); + + cache.set(cacheKey, promise); + } } - return this; } } @@ -327,7 +335,11 @@ function getCacheKey( // Private: given the DataLoader's options, produce a CacheMap to be used. function getValidCacheMap( options: ?Options -): CacheMap> { +): ?CacheMap> { + var shouldCache = !options || options.cache !== false; + if (!shouldCache) { + return null; + } var cacheMap = options && options.cacheMap; if (!cacheMap) { return new Map();