提问者:小点点

不知道如何在API调用后使用csv-writer逐行编写csv文件


我的用例如下。我有一个Node.js应用程序,它通过外部库limiter限制API调用。然后,我以每秒27个调用的速率进行API调用,直到我完成了对包含一个参数的整个数组的循环,该参数需要传递给API。一旦我从API得到响应,我就想把这些数据保存在一个csv文件中。

我的想法是,一旦从API得到结果,就逐行编写csv文件。我正在使用csv-writer。

根据文件显示

“您可以通过多次调用writeRecords(但需要等待实现前一次writeRecords调用的承诺)将记录继续写入同一文件。”

promise.resolve()。然后(()=>CSVWriter.WriteRecords(records1))。然后(()=>CSVWriter.WriteRecords(records2))

我也一直在考虑让代码等到API调用完成并提示编写csv文件,然而,我不知道如何做到这一点。我在网上找不到类似的例子。它们似乎都是从一个对象/数组开始的。我还尝试为抛出的任何异常添加一个catch,尽管文档中没有建议这样做。沿着这条线的东西。

          Promise.resolve()
    .then(() => csvWriter.writeRecords(outp))
    .catch(err => console.log(err))

这是我的代码:

var RateLimiter = require('limiter').RateLimiter;
const createCsvWriter = require('csv-writer').createArrayCsvWriter;  

 var limiter = new RateLimiter(27, 'second', true);

let final = [xxxxxxxx, xxxxxxx, ..... ]

const csvWriter = createCsvWriter({
    header: ['NAME'],
    path: 'out.csv'
});

let outp = []
final.forEach((item, index) => {

//limit the API calls according to the limiter defined above
  limiter.removeTokens(1, () => {


    ExternalAPIcall({ number: item}, (error, response) => {
       if (error) {
         console.error(error)
       } else {
         console.log(response.status_message)

        output.push(response.status_message)]

         const records = output.map(NAME => [NAME])
              csvWriter.writeRecords(records)



       }
     })


   })
 })

我希望文件是逐行写入的,然后我可以使用append:true覆盖文件,如果需要的话,如文档中所示。但是,会抛出此错误。

(节点:3540)UnhandledPromiseRejectionWarning:未处理得承诺拒绝.这个错误可能是由于抛出一个没有catch块的异步函数内部,或者是由于拒绝了一个未用.catch()处理的承诺。(拒绝ID:86)(节点:3540)UnhandledPromiseRejectionWarning:TypeError:无法读取ArrayCSVStringifier.GetCSVLine(/users/xxxx/Desktop/Nodexcel/Node_Modules/csv-writer/dist/lib/csv-stringifier/Abstract.js:19:14)在(/users/xxxx/desktop/nodexcel/node_modules/csv-writer/dist/lib/csv-writer.js:24:55)在generator.next()在/users/xxxx/desktop/nodexcel/node_modules/csv-writer/dist/lib/csv-writer.js:7:71在new Promise()在__awaiter(这个错误可能是由于抛出一个没有catch块的异步函数内部,或者是由于拒绝了一个未用.catch()处理的承诺。(拒绝ID:88)

谢谢你抽出时间。

你好,J。

解决了:问题是writeRecords期望>like Array>,而我正在传递一个数组。https://github.com/ryu1kn/csv-writer/blob/86a57cae5d68f91d738318aff1de3b6d55d6b718/readme.md#csvwriterwriteRecordsRecordsRecords,此位解决了它。

const records=llenar.map(NAME=>[NAME])csvwriter.writeRecords(records)

我已经更新了上面的代码


共2个答案

匿名用户

如果您希望您的文件逐行写入,那么您必须等待这些承诺,promissione.all对您没有帮助。

但是,您可以使用.reduce方法使承诺顺序运行。

您可以尝试下面的代码:

null

var RateLimiter = require('limiter').RateLimiter;
var createCsvWriter = require('csv-writer').createArrayCsvWriter;
var limiter = new RateLimiter(27, 'second', true);

const csvWriter = createCsvWriter({
  header: ['NAME'],
  path: './out.csv'
});

/** Mocked module - you can delete this */
const nexmo = {
  numberInsight: {
    get: (item, cb) => {
      if (typeof cb !== 'function') {
        cb = () => {}
      }
      let msg = {
        status: 1,
        status_message: `${item.number} - have passed`
      };
      cb(null, msg);
    }
  }
}

var final = ['john', 'mike', 'elise', 'valentine']

final = final.reduce((accumulator, item, index) => {

  return accumulator.then(() => {

    return new Promise(resolve => {

      limiter.removeTokens(1, (err, remainingReq) => {

        if (err) {
          resolve(Promise.resolve(err.message));
        } else {

          nexmo.numberInsight.get({
            level: 'basic',
            number: item
          }, (error, response) => {

            if (error) {
              resolve(Promise.resolve(error.message));
            } else {

              csvWriter.writeRecords([
                [response.status_message]
              ]).then(() => {
                resolve(response.status_message)
              }).catch(writerErr => {
                resolve(writerErr.message);
              })

            }

          })

        }

      })

    })

  })
}, Promise.resolve());

final.then(lastPromiseResponse => {

  console.log('final', lastPromiseResponse)

}).catch(err => {
  console.log('final err', err);
})

匿名用户

请使用以下代码引用。这里,我从JSON对象(例如目的)中提取了密钥。

   let someObject = yourArray[0] // JSON array
   let csvHeader = [] 
   for(let key in someObject) {
     csvHeader.push({ id: key, title: key });
   }
    const csvWriter = createCsvWriter({
        path: csvFilePath,
        header: csvHeader
    });
    return await csvWriter.writeRecords(yourArray);