Node.js - 在流数据侦听器内处理等待的最佳方式(mbox 电子邮件解析)

问题描述 投票:0回答:1

我正在尝试编写一个脚本,计算 gmail 导出中我的 mbox 文件的每个发件人的电子邮件数量(10GB,150k 电子邮件),但我的结果 (sendersCount) 记录为空。

const { MboxStream } = require("node-mbox");
const fs = require("fs");
const simpleParser = require("mailparser").simpleParser;

const mboxFilePath = "gmail.mbox";
const sendersCount = {};

const mailbox = fs.createReadStream(mboxFilePath);
const mbox = MboxStream(mailbox, {});

mbox.on("data", async function (msg) {
    // `msg` is a `Buffer` instance
    console.log("got a message", msg.toString().substring(0, 30));
    const parsed = await simpleParser(msg);
    const sender = parsed.from.value[0].address;
    console.log("sender email", sender);
    sendersCount[sender] = (sendersCount[sender] || 0) + 1;
});

mbox.on("error", function (err) {
  console.log("got an error", err);
});

mbox.on("finish", function () {
  console.log("done reading mbox file");
  console.log(sendersCount); //TODO write to json file
});

在放弃尝试使用自定义分隔符手动拆分 fs.createReadStream 后,我开始使用 MboxStream(当我使用“时,最后一封电子邮件丢失了” 从 ") 开始,mbox 使用默认的行分割器正确记录了每封电子邮件。然后我无法弄清楚如何手动解析缓冲区,并且由于无论如何我都需要电子邮件中的相当多的字段,所以我决定使用 simpleParser,它是异步的。

看起来 mbox 事件侦听器(由于是转换流实现)不是为异步代码设计的 - 它不会等待“等待”完成 - “发件人电子邮件”日志出现在“完成读取 mbox 文件”日志之后.

我想尝试的第一件事是推送 simpleParser 承诺并调用 Promise.all,但我觉得解决 150k 承诺可能会影响我的情况下的性能,并且我需要这个脚本相当快地重复测试大量数据.

我查看了类似的流/等待问题,但答案要么不适合我,要么不明显适用:

我也愿意接受其他建议,以更好的方式解析大量 mbox 数据以进行统计。

node.js async-await stream email-parsing mbox
1个回答
0
投票
你的代码工作正常,我测试过。另外,如果您不喜欢

require('mailparser').simpleParser

,您可以使用
require('mailparser').MailParser
。正如官方文档中所示,
.MailParser
必须比
.simpleParser
更快,因为它的级别较低。

https://nodemailer.com/extras/mailparser/

该模块公开了两种独立的模式,一个较低级别的 MailParser 类 和 simpleParser 函数。后者使用起来更简单(因此 名称),但资源效率较低,因为它缓冲附件内容 记忆中。

© www.soinside.com 2019 - 2024. All rights reserved.