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

Node.js中如何为现有JSON附加JSON并在Pug中使用

解决嵌套评论回复处理中的JSON解析与异步问题

我来帮你梳理下你遇到的问题:你写了两个处理评论回复的函数,发现不使用JSON.stringify的话,r.replies会显示成[Object],但用了之后在Pug里执行JSON.parse(replies)又报Unexpected end of JSON input错误。咱们一步步来解决。

问题表现与场景

当你直接把数组赋值给r.replies时,控制台会显示[Object],这只是字符串环境下的显示问题——JavaScript在直接打印对象数组时会默认转成[Object]字符串,但实际上r.replies还是一个有效的数组对象。

未使用JSON.stringify时r.replies显示为[Object]

而使用JSON.stringify后出现解析错误,本质是生成的JSON字符串不完整,这和你代码里的异步操作未正确等待有关。

你提供的相关代码

function getContentReplies(author, permlink) { 
  return new Promise((resolve, reject) => { 
    getReply(author, permlink, function (err, resp) { 
      if(err) reject(resp) 
      resp.map(r => { 
        r.body = marked(r.body) 
        if(r.children > 0) 
          return getContentReplies(r.author, r.permlink) 
            .then(c => { 
              let repliesArr = []; 
              for (var a = 0; a < c.length; a++) { 
                let i = { 
                  author: c[a].author, 
                  category: c[a].category, 
                  permlink: c[a].permlink, 
                  title: c[a].title, 
                  body: c[a].body 
                } 
                repliesArr.push(i); 
              } 
              r.replies = JSON.stringify(repliesArr); 
              return r; 
            }) 
        else return r 
      }) 
      resolve(resp); 
    }) 
  }) 
} 

async function getComments (username, permlink) { 
  console.log('-------------') 
  return new Promise((resolve, reject) => { 
    getReply(username, permlink, function (err, resp) { 
      if (err) console.log(err) 
      let promises = resp.map(r => { 
        r.body = marked(r.body) 
        if(r.children > 0) 
          return getContentReplies(r.author, r.permlink) 
            .then(c => { 
              let repliesArr = []; 
              for (var a = 0; a < c.length; a++) { 
                let i = { 
                  author: c[a].author, 
                  category: c[a].category, 
                  permlink: c[a].permlink, 
                  title: c[a].title, 
                  body: marked(c[a].body) 
                } 
                repliesArr.push(i); 
              } 
              r.replies = JSON.stringify(repliesArr); 
              return r; 
            }) 
        else return r 
      }) 
      Promise.all(promises) 
        .then(results => { 
          console.log(results); 
          return results; 
        }) 
        .catch(e => { 
          console.error(e); 
          reject(e); 
        }) 
      resolve(resp); 
    }) 
  }) 
}

补充的Replies对象结构

Replies对象内容

问题根源分析

  1. 异步操作未正确等待:在getContentReplies里,你用resp.map处理每个回复,其中包含异步的子回复加载,但你直接resolve(resp),根本没等这些异步操作完成。导致返回的resp中,很多r.replies还没被赋值,或者只赋值了一部分,后续JSON.parse自然会因为字符串不完整报错。
  2. getComments的resolve值错误:虽然你在getComments里用了Promise.all(promises),但最后还是resolve了原始的resp,而不是处理完成后的results,等于前面的异步处理白做了,返回的还是没处理完回复的原始数组。
  3. 不必要的JSON转换:其实Pug可以直接访问JavaScript对象,你完全不需要把数组转成JSON字符串再解析——这多此一举还容易出问题,之前的[Object]只是显示问题,不是对象本身无效。

解决方案

方案1:修复异步等待逻辑(若坚持用JSON转换)

先修改getContentReplies,确保等待所有异步操作完成后再返回结果:

function getContentReplies(author, permlink) { 
  return new Promise((resolve, reject) => { 
    getReply(author, permlink, async function (err, resp) { 
      if(err) return reject(resp); 
      // 用Promise.all等待所有回复的异步处理完成
      const processedResp = await Promise.all(resp.map(async r => { 
        r.body = marked(r.body); 
        if(r.children > 0) { 
          // 等待子回复加载完成
          const c = await getContentReplies(r.author, r.permlink); 
          const repliesArr = c.map(item => ({ 
            author: item.author, 
            category: item.category, 
            permlink: item.permlink, 
            title: item.title, 
            body: item.body 
          })); 
          r.replies = JSON.stringify(repliesArr); 
        } 
        return r; 
      })); 
      resolve(processedResp); 
    }) 
  }) 
}

再修改getComments,确保返回处理完成后的结果:

async function getComments (username, permlink) { 
  console.log('-------------') 
  return new Promise((resolve, reject) => { 
    getReply(username, permlink, function (err, resp) { 
      if (err) {
        console.log(err);
        return reject(err);
      } 
      const promises = resp.map(async r => { 
        r.body = marked(r.body); 
        if(r.children > 0) { 
          const c = await getContentReplies(r.author, r.permlink); 
          const repliesArr = c.map(item => ({ 
            author: item.author, 
            category: item.category, 
            permlink: item.permlink, 
            title: item.title, 
            body: marked(item.body) 
          })); 
          r.replies = JSON.stringify(repliesArr); 
        } 
        return r; 
      }) 
      Promise.all(promises) 
        .then(results => { 
          console.log(results); 
          resolve(results); // 返回处理后的结果,而非原始resp
        }) 
        .catch(e => { 
          console.error(e); 
          reject(e); 
        }) 
    }) 
  }) 
}

方案2:去掉JSON转换(更推荐)

既然Pug可以直接使用JavaScript对象,咱们直接赋值数组,省掉JSON序列化和反序列化的步骤:

修改两个函数中的r.replies = JSON.stringify(repliesArr);为r.replies = repliesArr;,同时修复异步等待逻辑,比如getContentReplies改成:

function getContentReplies(author, permlink) { 
  return new Promise((resolve, reject) => { 
    getReply(author, permlink, async function (err, resp) { 
      if(err) return reject(resp); 
      const processedResp = await Promise.all(resp.map(async r => { 
        r.body = marked(r.body); 
        if(r.children > 0) { 
          const c = await getContentReplies(r.author, r.permlink); 
          r.replies = c.map(item => ({ 
            author: item.author, 
            category: item.category, 
            permlink: item.permlink, 
            title: item.title, 
            body: item.body 
          })); 
        } else {
          r.replies = []; // 给无回复的项加空数组,避免Pug遍历报错
        }
        return r; 
      })); 
      resolve(processedResp); 
    }) 
  }) 
}

getComments同样修改resolve为results并去掉JSON相关代码,之后在Pug里直接遍历r.replies即可:

// Pug模板示例
each comment in comments
  .comment
    h3= comment.title
    .author= comment.author
    .body!= comment.body
    // 遍历子回复
    if comment.replies.length > 0
      .replies
        each reply in comment.replies
          .reply
            h4= reply.title
            .author= reply.author
            .body!= reply.body

这样既解决了[Object]的显示问题(控制台要查看完整结构,可用console.dir(r.replies)展开对象),又避免了JSON解析错误,代码也更简洁。

内容的提问来源于stack exchange,提问作者Gopesh Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:19:32