javascript - 将 JSON 数据流式传输到 React 会导致 JSON 输入意外结束

标签 javascript node.js reactjs stream

我正在尝试从 NodeJS 服务器传输大量数据,该服务器从 Mongo 获取数据并将其发送到 React。由于数据量相当大,我决定从服务器流式传输,并在数据传入后立即在 React 中显示。这是我在服务器上获得的内容的稍微简化的版本:

const getQuery = async (req, res) => {
const { body } = req;
const query = mongoQueries.buildFindQuery(body);
res.set({ 'Content-Type': 'application/octet-stream' });
Log.find(query).cursor()
  .on('data', (doc) => {
      console.log(doc);
      const data = JSON.stringify(result);
      res.write(`${data}\r\n`);
    }
  })
  .on('end', () => {
    console.log('Data retrieved.');
    res.end();
  });
};

这是 React 部分:

fetch(url, {  // this fetch fires the getQuery function on the backend
  method: "POST",
  body: JSON.stringify(object),
  headers: {
    "Content-Type": "application/json",
  }
})
  .then(response => {
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    const pump = () =>
      reader.read().then(({ done, value }) => {
        if (done) return this.postEndHandler();
        console.log(value.length);  // !!!
        const decoded = decoder.decode(value);
        this.display(decoded);
        return pump();
      });
    return pump();
  })
  .catch(err => {
    console.error(err);
    toast.error(err.message);
  });
}

display(chunk) {
  const { data } = this.state;
  try {
    const parsedChunk = chunk.split('\r\n').slice(0, -1);
    parsedChunk.forEach(e => data.push(JSON.parse(e)));
    return this.setState({data});
  } catch (err) {
    throw err;
  }
}

无论是顺利完成还是在 React 方面失败,都是 50/50。当失败时,总是因为 parsedChunk.forEach 中的 JSON 对象不完整。我做了一些挖掘,结果发现每次失败时,我用 3 个感叹号标记的 console.log 显示 65536。我 100% 确定它与我的流实现有关,并且我没有正确对 block 进行排队,但我不确定是否应该在客户端或服务器端修复它。任何帮助将不胜感激。

最佳答案

不是实现您自己的类似 NDJSON 的流式 JSON 协议(protocol)(您基本上在这里执行的操作)(将流划分为 block 和数据包的所有陷阱并不总是在您的控制之下),您可以看一下一些为满足您的需要而创建的现有工具,例如:

关于javascript - 将 JSON 数据流式传输到 React 会导致 JSON 输入意外结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54080710/

相关文章:

javascript - Angular ui.router 默认页眉页脚

javascript - 如何使用 React 在 Meteor 1.5.2 上进行分页?

node.js - 您可以在重定向期间将数据发送回 react 应用程序吗

node.js - npm 无法通过 Socks5 代理安装

reactjs - 修复标签宽度以正确使用概述的输入

javascript - 如何使用 React.js 中的 .map 函数更新显示

javascript - 如何使用 AJAX/jQuery 检查链接是否被单击

javascript - 如果我写 runat ="server",javascript 代码会出错

javascript - $x() 函数未在 Chrome 扩展、内容脚本中定义

mysql - 无法发送数据以在nodejs应用程序中查看