JSON Stringify 忽略 Redis 发布上的嵌套对象

Posted

技术标签:

【中文标题】JSON Stringify 忽略 Redis 发布上的嵌套对象【英文标题】:JSON Stringify ignores nested objects on Redis publish 【发布时间】:2019-10-14 20:37:55 【问题描述】:

我在后端使用 Redis 来扩展订阅。我正在使用this 库在我的javascript 代码之上实现redis。并使用猫鼬作为模型。

在 redis 发布期间,我必须对从 mongoose 获得的对象进行字符串化。我在订阅端解析它们并且一切正常,直到对象中有一个需要字符串化的嵌套对象。

所以如果我的对象是这样的:

 subtitle: '',
   description: '',
   checklists:
    [  _id: 5cee450c0fa29d0b54275da0, items: [] ,
       _id: 5cee455c0c31785b0875e09d, items: [] ,
       _id: 5cee47dc6d32e72c6411ce2d, items: []  ],
   attachments: [],
   labels: [],
   _id: 5ced1af26547233798f943f6,
   title: 'asfasf',
   box: 5cece1c3e6c3c13ff098658d,
   workflow: 5cece1cbe6c3c13ff0986591,

我收到:

 cardUpdated:
     
      subtitle: '',
      description: '',
      checklists: [ [Object], [Object], [Object] ],
      attachments: [],
      labels: [],
      _id: '5ced1af26547233798f943f6',
      title: 'asfasf',
      box: '5cece1c3e6c3c13ff098658d',
      workflow: '5cece1cbe6c3c13ff0986591',
     

当我发布时,我使用以下行:

pub.publish(types.CARD_UPDATED,
          JSON.stringify(
             cardUpdated: await getUpdatedCardStats(checklist.card) ,
          ));

注意:我知道我将 stringify 的参数包装在 中,如果没有它,嵌套对象将不会被忽略,但我需要这样做,因为我需要订阅端的键属性名称,即我是在多个地方使用具有不同键名的发布命令。

有没有办法解决这个问题来获得嵌套对象的字符串化?

编辑:事实证明,我在 Redis 的订阅端获得了正确的完整对象作为字符串,但实际上是 JSON.parse() 是罪魁祸首。解析后,它完全忽略了嵌套对象。有没有办法避免这种情况?

【问题讨论】:

【参考方案1】:

这不是一个有效的 JS 对象:

 _id: 5cee450c0fa29d0b54275da0, items: [] 

我认为这是_id: ObjectId, items: any[] 类型对象的.toString() 的输出,ObjectId 定义为here。在任何情况下,这个对象的 JSON 化都不是微不足道的,这就是为什么 JSON.stringify 简单地输出 [Object]

要绕过这个限制,您可以实现一个自定义函数来将您的对象转换为可以简单地 JSON 化的对象,可能需要 ObjectId.toString() 的帮助。

【讨论】:

我字符串化的 JSON 是从 mongoose 接收的,这可能就是它不将 id 包含在字符串引号中的原因。如果 id 在嵌套对象中无效,那么它也不应该对根对象起作用,因为根对象中也有一个 id。【参考方案2】:

试试:

const value = JSON.stringify(
    cardUpdated: await getUpdatedCardStats(checklist.card)
);
pub.publish(types.CARD_UPDATED, value);

【讨论】:

我确实试过了。事实证明,Redis 发布也可能会干扰这一点。在发布之前我 console.log 变量 value 在发布之前这是输出: "cardUpdated": "_id":"5cece46350a2804a34f31de7", "checklists":[ "_id":"5cee7e8176dce804e8d21e96", "items":[] 但是当在订阅的 redis 端收到它时,我得到了我在原始帖子中发布的内容。 控制台未正确发布。谢谢,现在可以使用了

以上是关于JSON Stringify 忽略 Redis 发布上的嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

kotlinx JSON.stringify 忽略空值

JSON.stringify()的深度使用

深度使用JSON.stringify()

JSON.stringify与JSON.parse

JS JSON.stringify 详解

你可能忽略的json的坑!!!