如何在Node.js中结合来自不同callback的数据?
我有多个函数在接收/parsing数据时被callback,我需要一个callback中的数据匹配到来自另一个callback的数据,这些数据发生在不同的时间。
例如,我有以下代码来使用pipedrive / inbox(github) client
和andres9 / mailparser(github) mailparser
接收电子邮件:
// List newest 10 messages client.listMessages(-5, function(err, messages){ messages.forEach(function(message){ var mailparser = new MailParser(); // setup an event listener when the parsing finishes mailparser.on("end", function(mail_object){ console.log("---------------------------------------------------------<<<"); console.log("Text body:", mail_object.text); // How are you today? console.log(">>>---------------------------------------------------------"); }); console.log(message.UID + ": Subject: < " + message.title + "> Flags: <" + message.flags + ">"); client.createMessageStream(message.UID).pipe(mailparser); //send the current email to the parser }); });
问题是,控制台显示消息的标题和标志一个接一个,首先,然后显示所有parsing的机构:
884: Subject: <[eBook] Executive's Guide to the Top 20 CSCs> Flags: <> 888: Subject: <Free Cloud-based Vulnerability Scanner> Flags: <\Seen> 896: Subject: <Unexpected sign-in attempt> Flags: <\Seen> 902: Subject: <[Watch] Backoff POS Malware: Key Indicators of Compromise> Flags: <$NotJunk> 918: Subject: <test subject 1> Flags: <$NotJunk> [... Then here are all the bodies ...] [... Message #884's body ...] [... Message #888's body ...] [... and so on ..]
当我想要
884: Subject: <[eBook] Executive's Guide to the Top 20 CSCs> Flags: <> [... Then message #884's body ...] 888: Subject: <Free Cloud-based Vulnerability Scanner> Flags: <\Seen> [... Then message #888's body ...]
最终,我将有这个应用程序发送完整的parsing消息(连同他们的parsing标题)到数据库,也浏览器,我需要的标志和其他元数据/头与parsing的身体配对,当我这样做,不逻辑分离通过callback。
Node.js中的最佳做法是什么? 对于相同的逻辑实体处理单独callback的标准方法是什么?有没有不同的方法来处理这个问题?
只要做end
听众的所有工作:
client.listMessages(-5, function(err, messages){ messages.forEach(function(message){ var mailparser = new MailParser(); // setup an event listener when the parsing finishes mailparser.on("end", function(mail_object){ console.log(message.UID + ": Subject: < " + message.title + "> Flags: <" + message.flags + ">"); console.log("---------------------------------------------------------<<<"); console.log("Text body:", mail_object.text); // How are you today? console.log(">>>---------------------------------------------------------"); }); client.createMessageStream(message.UID).pipe(mailparser); //send the current email to the parser }); });
这个很容易,因为你的调用是嵌套的。 有时你有多个asynchronous操作,一旦完成,你想要采取行动。 在这种情况下,使用蓝鸟这样的承诺库,并调用Promise.all()
。
只需将显示主题的console.log语句移动到显示主体的callback即
mailparser.on("end", function(mail_object){ console.log(message.title); console.log("---------------------------------------------------------<<<"); console.log("Text body:", mail_object.text); // How are you today? console.log(">>>---------------------------------------------------------");
加上gilly3的优秀答案,您可能需要显示从最新到最旧的数据。 我的示例使用messages.length作为开始键来构build一个对象,然后为每个消息递减它,直到达到“1”,这将是最新的/最新的消息。 然后很容易将对象从1循环到lastkey以正确输出。
// list newest 2 messages client.listMessages(-2, function(err, messages){ var newob = {}; var i = messages.length; messages.forEach(function(message){ var mailparser = new MailParser(); mailparser.on("end", function(mail_object){ console.log(message.UID+' '+message.title); /* because of loop direction i=1 will be latest/newest message to get last key we can use lastkey = Object.keys(newob).length; then loop from 1 to lastkey to output newest to last message. */ newob[i] = {}; newob[i]['UID'] = message.UID; newob[i]['from'] = mail_object.from; newob[i]['subject'] = mail_object.subject; newob[i]['title'] = message.title; newob[i]['text'] = mail_object.text; // count down 'i' so we know when at last message (i=0) i--; //now we're at end we can send object if(i===0){ endResponse(newob); } }); client.createMessageStream(message.UID).pipe(mailparser); }); });