我的用例如下。我有一个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)
我已经更新了上面的代码
如果您希望您的文件逐行写入,那么您必须等待这些承诺,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);