我正在尝试将 csv 文件的 header 放入数组中,并尝试使用 csv-parser 来执行此操作。有两件事我在这里想不通:
1) 为什么代码最后一行的 console.log 比其他任何东西都先触发?这也意味着我尝试记录的变量值未定义。
2) 为什么我的 getFields 函数不返回新填充的标题数组?我可以从函数内部控制台记录结果数组及其所有新元素,但实际上我无法返回充满元素的数组——它一直返回一个空数组。
代码如下:
const express = require('express')
const app = express()
const port = 3000
const csv = require('csv-parser')
const fs = require('fs')
function getFields (filePath) {
let results = [];
fs.createReadStream(filePath)
.pipe(csv())
.on('headers', (headers) => {
let values = Object.values(headers);
values.forEach(function(element) {
results.push(element);
});
console.log('I am actually getting results here: ', results);
return results;
});
}
const omg = getFields(thisIsAFilePath)
console.log('This console.log is firing before anything else: ', omg)
最佳答案
您的代码使用异步回调。这意味着,事件处理程序((headers) => {...}
函数)在触发事件(在本例中为 headers
)时执行。这是异步发生的,而其余脚本继续。
这意味着会发生以下情况:
- 函数声明
- 函数被调用,因为它什么都不返回(甚至没有
return
语句),undefined
存储在omg
< - 执行
console.log
调用 - 在未来的某个时候,事件
headers
被触发,将执行函数(headers) => { ... }
所以如果你需要结果,你需要把代码放在回调里面或者像这样从里面调用一个函数:
function handleHeaders(headers) {
console.log(headers);
}
function getFields (filePath) {
let results = [];
fs.createReadStream(filePath)
.pipe(csv())
.on('headers', (headers) => {
handleHeaders(headers);
});
}
替代方案: promise
或者,您可以使用 Promise API ,这将允许您像这样编写代码:
(async () => {
function getFields(filePath) {
return new Promise(resolve => {
let results = [];
fs.createReadStream(filePath)
.pipe(csv())
.on('headers', (headers) => {
let values = Object.values(headers);
values.forEach(function (element) {
results.push(element);
});
console.log('I am actually getting results here: ', results);
resolve(results);
});
});
}
const omg = await getFields(thisIsAFilePath)
console.log('This console.log is firing before anything else: ', omg)
})();
请记住,代码也是异步执行的,它只是以 Promises 的形式隐藏。
关于javascript - 使用 csv-parser Node 模块时的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56029298/