NextJS中修改result意外改变memcache数据的问题求助
问题:修改result对象意外改变memcache中的原始数据
我在开发NextJS项目时,用memcache存储实时数据,原本只想修改result里的数据但不影响缓存,结果每次改完result,缓存里的原始数据也跟着变了。相关代码如下:
const catagories = ["coding", "gaming", "tricks"]; console.log("Before::", cache.get("gaming")); // cache.get("gaming") => [{id: 1, likes: ['dev', 'lorem', 'ed'], dislikes: ['ram']}, {id: 2, likes: ['john', 'joe'], dislikes: ['loe', 'kun']}] let result = {}; catagories.map((catagory) => { result[catagory] = cache.get(catagory) || []; }) let username = req.body.username; // diana for(const catagory in result){ if(result[catagory] && result[catagory].length){ result[catagory].map((spack_live_data, idx) =>{ spack_live_data.is_liked = spack_live_data.likes.includes(username) spack_live_data.is_disliked = spack_live_data.dislikes.includes(username) spack_live_data.likes = spack_live_data.likes.length spack_live_data.dislikes = spack_live_data.dislikes.length }) } } console.log("After::", cache.get("gaming")); // cache.get("gaming") => [{id: 1, likes: 3, is_liked: false, dislikes: 1, is_disliked: false}, {id: 2, likes: 2, is_liked: false, dislikes: 2, is_disliked: false}]
问题原因
JavaScript里的对象、数组都是引用类型,当你执行result[catagory] = cache.get(catagory)时,并没有复制一份新的数据,只是把缓存里对象的内存引用赋值给了result。后续修改result里的对象属性,其实直接操作的是缓存里的原对象。
解决方法
要避免这个问题,你需要对缓存返回的数据做深拷贝,让result拿到完全独立的新对象,这样修改result就不会影响原缓存。
方案1:JSON序列化/反序列化(适合无特殊数据类型的场景)
修改赋值逻辑,通过JSON转译生成新对象:
catagories.map((catagory) => { const cacheData = cache.get(catagory) || []; // 深拷贝数据 result[catagory] = JSON.parse(JSON.stringify(cacheData)); })
方案2:手动递归深拷贝(适合含Date、函数等特殊类型的场景)
如果数据里有JSON序列化会丢失的类型,用递归实现拷贝:
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Array) { return obj.map(item => deepClone(item)); } const cloned = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { cloned[key] = deepClone(obj[key]); } } return cloned; } // 赋值时调用深拷贝 catagories.map((catagory) => { const cacheData = cache.get(catagory) || []; result[catagory] = deepClone(cacheData); })
修改后效果
执行代码后,cache.get("gaming")会保持原始结构:[{id: 1, likes: ['dev', 'lorem', 'ed'], dislikes: ['ram']}, {id: 2, likes: ['john', 'joe'], dislikes: ['loe', 'kun']}]
而result里的数据会是处理后的独立对象,完全不会影响缓存。
内容的提问来源于stack exchange,提问作者Malloc Calloc
相关产品推荐
相关产品推荐

