首页 > 解决方案 > 如何从 ExpressJS 流式传输 JSON 对象?

问题描述

我正在尝试将 JSON 对象从 ExpressJS / Node 后端 API 流式传输到前端站点。

由于各种原因,我不想使用 Sockets.IO。据我了解,本机流媒体库应该支持流媒体对象,看来只有 Express 使这变得复杂。

我的前端代码直接接缝。我使用 Fetch 获取目标 URL,从响应对象中获取读取流,并将读取流设置为 objectMode: true。

前端示例:

    async function () {

      let url = "myurl";

      let response = await fetch( url, {
        method: 'GET',
        mode: 'cors',
        wtihCredentials: 'include'
      }

      const reader = response.body.getReader({objectMode: true });

      // Where things are a bit ambiguous
      let x = true;
      while (x) {
        const {done, value} = reader.read()
        if (done) { break; }

        // do something with value ( I push it to an array )

      }      
}

后端波德示例(由于我无法将流更改为 objectMode 而失败)

router.get('/', (request, response) => {

  response.writeHead(200, { 'Content-Type' : 'application/json' });

  MongoDB.connection.db.collection('myCollection').find({}).forEach( (i) => {
    response.write(i);
  }).then( () => {
    response.end()
  })
})

现在我的问题是似乎没有办法将 ExpressJS 写入流更改为 objectMode:true。令我沮丧的是,ExpressJS 文档甚至没有承认响应对象上存在 write() 函数:https ://expressjs.com/en/api.html#res

如何将其更改为 objectMode: true ?

相反,我尝试将 writeStream 作为字符串使用。我遇到的问题是,当发送缓冲区填满时,它是通过字符而不是对象来完成的。这意味着在某些时候无效的 JSON 被传递给请求者。

我经常遇到的一个建议解决方案是我可以读取客户端上的所有块并组装有效的 JSON。这违背了流媒体的目的,所以我试图找到更好的方法。

对于我认为是同样的问题,我无法弄清楚如何从 express 代码中直接与写入流对象对话,因此我无法使用本机 writeStream 操作 writable.length 来手动检查是否有空间将整个 JSON 对象作为字符串。这使我无法使用带有新行终止符的字符串化 JSON。

https://nodejs.org/api/stream.html#stream_writable_writablelength

https://nodejs.org/api/stream.html#stream_writable_writableobjectmode

有人可以让我直截了当吗?我正在使用 Mongo 数据库中的 100k + 记录,我真的需要部分页面加载才能工作,以便用户可以开始挑选数据。

标签: javascriptnode.jsjsonexpress

解决方案


推荐阅读