{"id":44872,"library":"exp-asynccache","title":"exp-asynccache","description":"An async cache for Node.js (v3.2.0) that provides a lookup function per key with callback and promise support. Released under the ExpressenAB organization. Differentiates from similar libraries like async-cache by not caching errors, always calling the callback asynchronously, and allowing per-key TTL via additional arguments to the resolve function. Uses lru-cache by default but supports any compatible cache interface. Stable maintenance mode; low release cadence.","status":"maintenance","version":"3.2.0","language":"javascript","source_language":"en","source_url":"git://github.com/ExpressenAB/exp-asynccache","tags":["javascript","cache","async"],"install":[{"cmd":"npm install exp-asynccache","lang":"bash","label":"npm"},{"cmd":"yarn add exp-asynccache","lang":"bash","label":"yarn"},{"cmd":"pnpm add exp-asynccache","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Optional; default caching strategy. Any compatible cache can be used instead.","package":"lru-cache","optional":true}],"imports":[{"note":"CommonJS-only; no ESM or named exports. Default export via require.","wrong":"import AsyncCache from 'exp-asynccache'","symbol":"AsyncCache","correct":"var AsyncCache = require('exp-asynccache')"},{"note":"Constructor must be called with 'new'; omitting it may cause errors or unexpected behavior.","wrong":"AsyncCache() without new","symbol":"AsyncCache constructor","correct":"new AsyncCache()"},{"note":"Second argument must be a function that receives resolve; passing resolve directly causes incorrect behavior.","wrong":"cache.lookup('key', resolve, callback)","symbol":"cache.lookup callback","correct":"cache.lookup('key', function(resolve) { ... }, callback)"}],"quickstart":{"code":"var AsyncCache = require('exp-asynccache');\nvar cache = new AsyncCache();\n\n// Callback usage\ncache.lookup('mykey', function(resolve) {\n  // Simulate async fetch\n  setTimeout(function() {\n    resolve(null, 'cached value');\n  }, 100);\n}, function(err, value) {\n  if (err) console.error(err);\n  else console.log(value); // 'cached value'\n});\n\n// Promise usage\nvar promise = cache.lookup('mykey2', function(resolve) {\n  resolve(null, { data: 42 });\n});\npromise.then(console.log).catch(console.error);\n\n// With custom TTL per key (for lru-cache)\ncache.lookup('ephemeral', function(resolve) {\n  resolve(null, 'short-lived', 2000); // expires in 2 seconds\n}, function(err, value) {\n  console.log(value);\n});","lang":"javascript","description":"Demonstrates callback and promise usage of cache.lookup, including per-key TTL."},"warnings":[{"fix":"Ensure the cache key encompasses all variables that affect the result, e.g., concatenate name+location for a person lookup.","message":"Cache key must include all data used to compute the value","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Handle errors in the lookup function by retrying or logging; do not rely on error caching.","message":"Errors are not cached; subsequent lookups for same key after an error will re-execute the lookup function","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Do not assume synchronous behavior; always treat callback as async.","message":"Callback is always called asynchronously even if value is resolved synchronously","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Update lookup calls to use a function that receives resolve instead of passing resolve directly.","message":"Version 2.0.0 removed deprecated callback style where resolve was passed directly","severity":"breaking","affected_versions":">=2.0.0"}],"env_vars":null,"search_vec":"'addit':51 'allow':45 'alway':39 'argument':52 'async':5,33,77 'async-cach':32 'asynccach':3 'asynchron':43 'cach':6,34,37,60,67,76 'cadenc':74 'call':40 'callback':18,42 'compat':66 'default':62 'differenti':27 'error':38 'exp':2 'exp-asynccach':1 'expressenab':25 'function':14,56 'interfac':68 'javascript':75 'key':16,48 'librari':30 'like':31 'lookup':13 'low':72 'lru':59 'lru-cach':58 'mainten':70 'mode':71 'node.js':8 'organ':26 'per':15,47 'per-key':46 'promis':20 'provid':11 'releas':22,73 'resolv':55 'similar':29 'stabl':69 'support':21,64 'ttl':49 'use':57 'v3.2.0':9 'via':50","created_at":"2026-06-07T12:52:15.785813+00:00","updated_at":"2026-06-07T12:52:15.785813+00:00","problems":[{"fix":"Install latest version: npm install exp-asynccache@3.2.0","cause":"AsyncCache module not imported correctly or outdated version without lookup method.","error":"TypeError: cache.lookup is not a function"},{"fix":"Wrap resolve in a function: function(resolve) { ... resolve(...) }","cause":"Second argument to lookup is not a function wrapper; likely passed resolve directly.","error":"TypeError: resolve is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/ExpressenAB/exp-asynccache#readme","github":"git://github.com/ExpressenAB/exp-asynccache","docs":null,"changelog":null,"pypi":null,"npm":"exp-asynccache","openapi_spec":null,"status_page":null,"smithery":null,"categories":["storage"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}