繁体   English   中英

如何解决Node.js中的“无法读取未定义的属性”

[英]How to resolve “Cannot read property of undefined” in Node.js

我是JS的新手,我需要为测试数据创建简单的CSV解析器。 我有一个非常奇怪的问题。

这是我测试的代码:

'use strict';

const assert = require('assert');
const HomePage = require('../pages/HomePage');
const csv = require('../tools/CsvReader');

describe('Check if values are correct', () => {

    let dataProvider = csv.readFromCsv("test/resources/places.csv");

    function valuesTest(city, expectedLat, expectedLong) {
        it('Data must match', () => {
            let searchPlace = HomePage
                .open()
                .findByPlaceName(city)
                .getSearchPlace();
            assert.strictEqual(searchPlace.getLatitude(), expectedLat);
            assert.strictEqual(searchPlace.getLongtitude(), expectedLong);
            console.log(dataProvider[0].CITY);
        });
    }

    for (let i = 0; i < dataProvider.length; i++) {
        valuesTest(dataProvider[i].CITY, dataProvider[i].LAT, dataProvider[i].LONG)
    }

});

和我的CSV阅读器的代码:

'use strict';

const csv = require('csv-parser');
const fs = require('fs');

class CsvReader {


    readFromCsv(path) {
        let results = [];

        fs.createReadStream(path)
            .pipe(csv())
            .on('data', (data) => results.push(data));
        return results;
    }

}

module.exports = new CsvReader();

这是我的CSV:

CITY,LAT,LONG
Kyiv,50.447731,30.542721
Lviv,49.839684,24.029716
Ivano-Frankivsk,48.922634,24.711117

问题如下:为什么我可以在“ valuesTest”块中使用变量“ dataProvider”,它可以正常工作并返回CITY变量的值,但是在“ for”循环中,我不能使用它(变量“ dataProvider”,“ CITY”等在此处不可用),尽管它们位于同一块“描述”中。

CSV阅读器是异步操作。 我怀疑您的for循环即使在解析csv并返回值之前也已执行。 尝试将for循环放入函数中,并作为回调传递给readFromCsv函数。 在数据事件上调用此函数,您将在该事件上确保获得数据。

您应该将回调传递给readFromCsv ,当createReadStream完成时将执行该回调。 您可以通过侦听其end事件来确定createReadStream何时完成。 例如,请参阅csv-parser示例代码 )。

就您而言,您可以执行以下操作:

readFromCsv(path, onEnd) {
    let results = [];

    fs.createReadStream(path)
        .pipe(csv())
        .on('data', (data) => results.push(data))
        .on('end', () => onEnd(results));
}

csv.readFromCsv("test/resources/places.csv", function onData(data) {
    for (let i = 0; i < data.length; i++) {
        valuesTest(data[i].CITY, data[i].LAT, data[i].LONG);
    } 
});

您应该使用end事件而不是data事件来确定流何时完成。 如果您在第一个data事件之后返回,则可能无法获取所有数据。

每个数据块都会触发一次data事件。 如果您的数据中有多个“块”,则如果返回数据回调,则会将其截断。 有关不同事件类型的详细信息,请参见nodeJS文档 您可能不会注意到较小的测试文件会有所不同,但是制作较大的文件会看到差异。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM