如何在Dojo中实现缓存?解决产品代码列表重复请求问题
解决方案与建议
针对你在Dojo Widget中缓存10K条产品代码列表的需求,这里有几个可行的实现方案,都是Dojo生态里常用的,完全避开cookie的限制:
1. 使用dojo/store/Cache(推荐,Dojo 1.x原生方案)
Dojo的dojo/store/Cache就是专门为这类场景设计的,它能把底层数据存储(比如用JsonRest发起HTTP请求)和缓存存储(比如Memory)结合起来。第一次请求时会从服务端拉取数据并自动存入缓存,后续读取操作直接从缓存获取,完全不用你手动处理逻辑。
示例代码大概是这样的:
require([ "dojo/store/JsonRest", "dojo/store/Memory", "dojo/store/Cache", "dojo/domReady!" ], function(JsonRest, Memory, Cache) { // 定义远程数据存储 var productStore = new JsonRest({ target: "/api/product-codes" // 你的服务端接口地址 }); // 包装成带缓存的存储 var cachedProductStore = Cache(productStore, new Memory()); // 在你的Widget里使用这个缓存后的store // 第一次调用会发请求,之后直接读内存缓存 cachedProductStore.query().then(function(productCodes) { // 把数据渲染到Filtering Select yourFilteringSelect.set("store", cachedProductStore); }); });
这个方案的好处是完全利用Dojo原生API,逻辑简洁,内存缓存足够应对10K条数据的规模。
2. 手动维护dojo/store/Memory缓存
如果你想更灵活地控制缓存时机(比如只在特定条件下缓存),可以自己维护一个Memory存储作为缓存:
require([ "dojo/store/JsonRest", "dojo/store/Memory", "dojo/promise/when", "dojo/domReady!" ], function(JsonRest, Memory, when) { var productCache = null; var productRemoteStore = new JsonRest({ target: "/api/product-codes" }); function getProductCodes() { if (productCache) { // 缓存存在,直接返回缓存数据的Promise return when(productCache.query()); } // 缓存不存在,发起请求并存入缓存 return productRemoteStore.query().then(function(data) { productCache = new Memory({ data: data }); return data; }); } // 在Widget中调用 getProductCodes().then(function(codes) { yourFilteringSelect.set("store", productCache); }); });
这种方式适合需要自定义缓存失效逻辑的场景,比如定时清理缓存或者根据某些业务条件刷新缓存。
3. 结合localStorage实现持久化缓存
如果需要页面刷新后依然保留缓存(内存缓存会在页面关闭后丢失),可以用浏览器的localStorage来存储数据,配合Memory store使用:
require([ "dojo/store/JsonRest", "dojo/store/Memory", "dojo/promise/when", "dojo/domReady!" ], function(JsonRest, Memory, when) { var CACHE_KEY = "product_codes_cache"; var productCache = null; function loadCacheFromLocalStorage() { var cachedData = localStorage.getItem(CACHE_KEY); if (cachedData) { try { return new Memory({ data: JSON.parse(cachedData) }); } catch(e) { // 解析失败,清空缓存 localStorage.removeItem(CACHE_KEY); } } return null; } function saveCacheToLocalStorage(data) { try { localStorage.setItem(CACHE_KEY, JSON.stringify(data)); } catch(e) { // 存储失败(比如空间不足),忽略即可 console.warn("Failed to save product codes to localStorage", e); } } function getProductCodes() { productCache = loadCacheFromLocalStorage(); if (productCache) { return when(productCache.query()); } return new JsonRest({ target: "/api/product-codes" }).query().then(function(data) { productCache = new Memory({ data: data }); saveCacheToLocalStorage(data); return data; }); } // 在Widget中使用 getProductCodes().then(function(codes) { yourFilteringSelect.set("store", productCache); }); });
10K条产品代码序列化后体积很小,远低于localStorage的5MB限制,完全不用担心空间问题。如果服务端数据更新了,记得提供一个清理缓存的逻辑(比如增加版本号,或者监听服务端的更新通知)。
学习资源参考
- Dojo官方文档中关于
dojo/store模块的章节,重点看Cache、Memory和JsonRest的API说明,里面有详细的使用示例和参数解释。 - Dojo官方教程里的「Working with Data Stores」主题,其中专门有小节讲解缓存策略的实现,能帮你更深入理解Dojo存储体系的设计思路。
- 如果你用的是Dojo 2.x(现名@dojo/framework),可以参考它的
@dojo/stores包,里面有更现代化的状态管理和缓存方案,不过Dojo 1.x的方案依然是目前最广泛使用的。
内容的提问来源于stack exchange,提问作者Shital
相关产品推荐
相关产品推荐

