我想对我如何编写以下代码进行健全性检查。该代码列出来自电子邮件帐户的3条消息,然后下载并解析每个消息正文,并将结果保存到Mongo数据库。虽然这是Node.js代码,但我认为我的问题一般是javascript。在我第一次尝试(下面显示的代码)时,相同的消息打印到控制台并被保存到数据库3次。预期的功能是将3个不同的消息保存到数据库中。我认为该问题与messages[x]
没有通过变量"end"
正确发送到发出的objMessageHeader
事件有关,所以在第二个代码示例中我添加了一个IIFE(立即调用的函数)表达式)如图所示。现在,3条消息正确下载到数据库,而不是下载并将相同的消息保存3次到数据库。
我忍不住认为IIFE解决方案是hackish。这是正确的方法吗?这是一个反模式,是否有更好或不同的方式?如果您不确定如何回答,也许您可以解释为什么第一次尝试不起作用而第二次尝试不起作用。
注意:client.createMessageStream(... objMailParser)
行最终会触发objMailParser
的{{1}}事件。
这是我的第一次尝试,它无法正常工作并将相同的消息保存3次到数据库:
"end"
这是带有IIFE(立即调用的函数表达式)的修改后的代码,它可以正常工作,将3个单独的消息保存到数据库中:
client.listMessages(-3, function(err, messages){
for (var x=0; x <= messages.length-1; x++) {
var objMessageHeader = messages[x];
var objMailParser = new MailParser();
objMailParser.on("end", function(objParsedMessage){
console.log("["+objMessageHeader.UIDValidity+"."+objMessageHeader.UID+"] Subject: <"+objMessageHeader.title+"> Flags: <"+objMessageHeader.flags+">");
console.log("---------------------------------------------------------<<<");
console.log("From:", objParsedMessage.from);
console.log("Subject:", objParsedMessage.subject);
console.log("Text body:", objParsedMessage.text);
console.log(">>>---------------------------------------------------------");
var objMessage = objMessageHeader;
objMessage.type = "message";
objMessage.account = "someemail@yahoo.com";
objMessage.mailboxPath = strMailboxPath;
objMessage.parsedMessage = objParsedMessage;
saveMessageToDBMongo("first100", strMailboxPath, collMessages, objMessage);
}); // objMailParser.on("end" ...
client.createMessageStream(objMessageHeader.UID).pipe(objMailParser);
} // for (var x=0 ...
}); // client.listMessages ...
答案 0 :(得分:0)
在循环闭包内只有一个x变量的副本,并且所有绑定都看到相同的值。如果要在绑定中使用x
,则需要打破循环并为每个绑定使用新范围(这可以通过IIFE完成)。您的邮件正在保存3次,因为x
始终为3
检查这个小提琴:http://jsfiddle.net/vc149s70/
如果查看setTimeout()
控制台日志,结果始终为test3
,但在MailParser()
超时时结果是正确的。
使用IIFE是解决此问题的正确方法,因为您只需创建新范围并传入x
。还有很多其他方法可以做到这一点,但我认为在你的情况下,IIFE是好的。