Когда я помещаю значения в массив асинхронно, размер массива увеличивается, но значения остаются пустыми

#javascript #node.js

#javascript #node.js

Вопрос:

У меня есть следующий код. Ошибка в коде, потому что массив писем заполнен нулевыми значениями. Однако при отладке запускается событие ‘row’, и объект данных действительно обладает этим свойством .Email . Например, объект данных указан правильно {Email:'jon.doe@example.com'} , однако строка emails.push(data.Email); приводит к тому, что массив писем имеет правильную длину, но заполнен нулевыми значениями. [null,null,null...] Как это вообще возможно? Я использую Node.js 14.15

     const emails = [];
    await new Promise((resolve,reject)=>{
        parser.on('row',(data)=>{
            emails.push(data.Email);
        });
        parser.on('done',()=>{
            return resolve();
        });
        parser.on('error',(error)=>{
            console.error(error);
            return reject(error);
        });
        parser.getEmails(path.join(folder,file));
    });
    console.log(emails.length   ' emails loaded');
  

Комментарии:

1. Что вы видите, если используете console.log(data.Email) ?

2. Как вы просматриваете data объект? Я подозреваю, что что-то изменяет его асинхронно, и консоль показывает вам обновленное содержимое, которого не было, когда вы это делали emails.push()

3. @Barmar console.log(data.Email) — это электронное письмо, console.log(JSON.stringify(data)) показывает объект со свойством email, возможно, вы правы в отношении асинхронной модификации

4. скрипт одновременно ничего не делает, как вы думаете, строки могут собирать мусор вместе с объектом?

5. Нет. Сборка мусора этого не делает.

Ответ №1:

Короче говоря, я предполагал, что свойство было правильно помечено Email . Однако оказалось, что поле было на самом деле [random invisible ascii control character]Email . Поэтому, конечно, вывод строк на консоль не будет указывать на проблему для визуального осмотра. После долгих усилий и переноса производственного файла на сторону разработки и изучения кода в отладчике я смог определить, что имя ключа отличается от ожидаемого. Таким образом, более надежный код получается примерно таким:

     let emails = [];
    await new Promise((resolve,reject)=>{
        parser.on('row',(data)=>{
            emails.push(data);
        });
        parser.on('done',()=>{
            return resolve();
        });
        parser.on('error',(error)=>{
            console.error(error);
            return reject(error);
        });
        parser.getEmails(path.join(folder,file));
    });
    if(emails.length === 0) {
        return; //handle no emails here
    }
    const key = Object.keys(emails[0]).filter(i=>i.includes('Email'));
    if(key.length === 0) {
        return; //handle improper field title here
    }
    emails = emails.map(i=>i[key[0]]);
    console.log(emails.length   ' emails loaded');