CSV 转换为 JSON 以空数组形式返回

问题描述

我的 next.js 项目中有一个 API 路由,想法是它处理来自我工作的公司正在使用的 API 的统计信息。它可以毫无问题地完成整个函数,直到需要将 CSV 转换为 JSON 数组,然后才返回 []

我想出了是否删除 CSVtoJSON 转换代码并运行以下载文件,然后更改代码使其具有 CSVtoJSON 代码,但删除文件下载后,它会将 CSV 解析为我想要的 JSON,没有问题。

我正在使用 asyn/await 函数,所以当我尝试将文件作为一个整体运行时,我不确定为什么它会将文件读取为空,但如果我单独运行每个块则不会。

// logs.ts
import {NextApiRequest,NextApiResponse} from 'next'
import {processstats,fetchCsv,downloadFile} from './functions'

export default async (req: NextApiRequest,res: NextApiResponse) => {
 const request = await processstats(1,1,'UTC','records','calls')
 const csv_url = await fetchCsv(request.request_id)
 const parsedf = await downloadFile(csv_url.download_url)
 res.status(200).json(parsedf)
}
// downloadFile function
export async function downloadFile(url) {
  const fs = require('fs')
  const https = require('https')
  const csv = require('csvtojson')

  const fp = await fs.createWriteStream('pages/api/stats/data.csv')
  const req = await https.get(url,function (res) {
    res.pipe(fp)
  })

  const jsonArray = await csv().fromFile('pages/api/stats/data.csv')
  return jsonArray
}

不会抛出任何错误,它只是发送回空的 [] 数组。

非常感谢任何帮助。

苹果

解决方法

 const fp = await fs.createWriteStream('pages/api/stats/data.csv')
 const req = await https.get(url,function (res) {
    res.pipe(fp)
 })

只等待微任务队列作业运行,因为 https.get 不返回承诺。需要重写它来处理从 get 请求到管道的所有数据的获取和写入,并可能在启动对

的调用之前关闭管道
 const jsonArray = await csv().fromFile('pages/api/stats/data.csv')

最好的资源是 https.gethttp.get 组合的文档。据我了解,需要监控响应对象上触发的 dataend 事件。

在(站点)搜索框中使用“[node.js] http.get data chunk]”搜索此站点以获取更多信息。

,

就在我要放弃的时候,我想出了如何解决这个问题。

我需要做的就是使用 fs.readFileSync('pages/api/stats/data.csv) 将文件内容读入一个字符串,然后使用 return csv().fromString(data.toString())

这奏效了。下面的最终代码。

export async function downloadFile(url) {
  const https = require('https')
  const fs = require('fs')
  const fp = fs.createWriteStream('pages/api/stats/data.csv')
  const csv = require('csvtojson')

  https.get(url,function (res) {
    res.pipe(fp)
  })
  var data = fs.readFileSync('pages/api/stats/data.csv')
  return csv().fromString(data.toString())
}