You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:50:43