ReactJS извлекает полный CSV

#reactjs #fetch #papaparse #react-highcharts

Вопрос:

Я пытаюсь извлечь и проанализировать CSV-файл в своем проекте ReactJS. Я читаю из потока фрагмент за фрагментом, а затем разбираю его на пары значений [Дата,данные]. Намерение состоит в том, чтобы затем использовать массив значений для загрузки графика Highcharts/Highstock.

 import React, { useEffect, useState } from 'react';
import HighchartsReact from 'highcharts-react-official';
import HighStock from "highcharts/highstock";

import Papa from 'papaparse';

async function readAndParseData() {
  const response = await fetch(dataURI)
  const reader = response.body.getReader()
  const decoder = new TextDecoder('utf-8')

  let values = []

  //Keep reading in chunks until finished
  let value, done;
  while (!done) {
    ({ value, done } = await reader.read());
    if (done) {
      break
    }

    const csv = decoder.decode(value) // the csv text
    const results = await Papa.parse(csv, { header: false }) // object with { data, errors, meta }
    const rows = results.data // array of objects

    //Put data into [[x1,y2], [x2,y2], ...] format
    rows.slice(1).forEach(ele => {
      values.push([Date.parse(ele[0]), parseFloat(ele[2])])
    });
    return values
  }
}


useEffect(() => {

  //Gets and sets graph data
  async function getGraphData() {
    let graphData = await readAndParseData()
    console.log(graphData)
    setDataSource(graphData)
  }
  getGraphData()

}, []);
 

Проблема, с которой я сталкиваюсь, заключается в том, что я не всегда получаю полные данные CSV, а иногда это просто первый фрагмент или несколько фрагментов. Я попробовал asyncs и ожидает, чтобы он возвращался только после завершения всего потока и всех данных в массиве значений. Что я здесь упускаю?

Ваше здоровье!

Ответ №1:

Для всех, кто застрял на этом, вот что я сделал:

 import React, { useEffect, useState } from 'react';
import HighchartsReact from 'highcharts-react-official';
import HighStock from "highcharts/highstock";

import Papa from 'papaparse';

async function readAndParseData() {
    const response = await fetch(dataURI)
    const reader = response.body.getReader()
    const decoder = new TextDecoder('utf-8')

    //Keep reading in chunks until finished
    let csvText = ""
    let value, done;
    while (!done) {
      ({ value, done } = await reader.read());
      if (done) {
        break
      }

      const csv = decoder.decode(value) // the csv text
      csvText = csvText.concat(csv) //concat new csv chunk
    }

    const results = await Papa.parse(csvText, { header: false }) // object with { data, errors, meta }
    const rows = results.data // array of objects

    //Put data into [[x1,y2], [x2,y2], ...] format
    let values = []
    rows.slice(1).forEach(ele => {
      values.push([Date.parse(ele[0]), parseFloat(ele[2])])
    });

    return values
  }


  useEffect(() => {

    //Gets and sets graph data
    async function getGraphData() {
      let graphData = await readAndParseData()
      setDataSource(graphData)
    }
    getGraphData()

  }, []);

 

Просто продолжайте считывать все данные и декодировать их в одну строку кусок за куском. Затем, после того как все данные будут прочитаны, преобразуйте и установите их.