1

In my Vue.js application, I had to parse CSV file and upload each line to the backend. I would like to do it asynchronously so that the reading of the next record takes place after the previous record is already uploaded (promise resolved).

import parse from 'csv-parse';

importCsv() {
  const parser = parse()
  
  let index = 0;
  parser.on('readable', async () => {
    let record = parser.read()
    if(record) {
      await new Promise((resolve) => setTimeout(resolve, 1000))
      index++
      console.log("record nr ",index)
    }
  })      
  
  parser.on('error', (err) => {
    console.log(err)
  })

  parser.on('end', () => {
    console.log("finish")
  })

  parser.write(this.fileContent)
  parser.end()
}

this.fileContent is a file content saved in my component as string.

Even if I put await statement before promise and async before readable event callback, it still not working as it should.

actual_output

Currently, the word 'finish' appears first, which means that parsing is over. Then, after 1 second, 9 console logs are displayed at once

I would like output with the record number to appear every 1 second, and then at the end the console log "finish".

trincot
  • 317,000
  • 35
  • 244
  • 286
Przemek Baj
  • 426
  • 2
  • 5
  • 18
  • 1
    The question is mistakenly focused on Vue, while this is Node question. You don't chain promises so you can't expect that they will run in the order you want. You need to promisify the stream.The most straightforward way is to stick to async iterators and async/await, because Node streams are conveniently translated to them. See https://csv.js.org/parse/api/async_iterator/ – Estus Flask May 27 '21 at 17:52
  • @EstusFlask I know that question is not focused on Vue, I just wanted to provide a context. I'll try Your example, thank You very much for your help! – Przemek Baj May 27 '21 at 19:47

0 Answers0