Javascript 如何在Node.js中组合来自不同回调的数据?

Javascript 如何在Node.js中组合来自不同回调的数据?,javascript,node.js,Javascript,Node.js,我有多个函数,它们在接收/解析数据时使用数据回调,我需要一个回调中的数据与另一个回调中的数据匹配,而另一个回调在不同的时间发生 例如,我使用pipedrive/inbox(github)client和andres9/mailparser(github)mailparser接收电子邮件的代码如下: // List newest 10 messages client.listMessages(-5, function(err, messages){ messages.forEach(func

我有多个函数,它们在接收/解析数据时使用数据回调,我需要一个回调中的数据与另一个回调中的数据匹配,而另一个回调在不同的时间发生

例如,我使用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

    });
});
//列出最新的10条消息
client.listMessages(-5,函数(err,messages){
messages.forEach(函数(消息){
var mailparser=new mailparser();
//在解析完成时设置事件侦听器
mailparser.on(“end”,函数(mail\u对象){
console.log(“---------------------------------------------------------------------------------------------------------------------------------------”);
});
console.log(message.UID+”:主题:<“+message.title+”>标志:”;
createMessageStream(message.UID).pipe(mailparser);
//将当前电子邮件发送到解析器
});
});
问题是,控制台先显示消息标题和标志,然后依次显示所有已解析的正文:

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:主题:标志:
[…然后是消息#884的正文…]
888:主题:旗帜:
[…然后是消息#888的正文…]
最终,我会让这个应用程序将完整解析的消息(连同解析的消息头)发送到数据库和浏览器,我需要在执行此操作时,将标记和其他元数据/消息头与解析的正文配对,而不是通过回调在逻辑上分开


Node.js中实现这一点的最佳实践是什么?处理同一逻辑实体的单独回调的标准方法是什么?有不同的方法处理吗?

只需将显示主题的console.log语句移动到显示主体的回调中即可

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(">>>---------------------------------------------------------");
mailparser.on(“end”,函数(mail\u对象){
console.log(message.title);
console.log(“---------------------------------------------------------------------------------------------------------------------------------------”);

只需完成
结尾中的所有工作
侦听器:

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
    });
});
client.listMessages(-5,函数(err,messages){
messages.forEach(函数(消息){
var mailparser=new mailparser();
//在解析完成时设置事件侦听器
mailparser.on(“end”,函数(mail\u对象){
console.log(message.UID+”:主题:<“+message.title+”>标志:”;
console.log(“---------------------------------------------------------------------------------------------------------------------------------------”);
});
createMessageStream(message.UID).pipe(mailparser);
//将当前电子邮件发送到解析器
});
});

这很容易,因为您的调用是嵌套的。有时您有多个异步操作,需要在它们全部完成后执行这些操作。在这种情况下,请使用像and call
promise.all()这样的承诺库

除了gilly3的优秀答案之外,您可能需要从最新到最旧显示数据。我的示例使用messages.length作为起始键构建一个对象,然后为每条消息减小该值,直到到达“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);

            });
  });

哇,这太简单了!我还不习惯回调,所以我还在学习。我没有意识到“end”调用的函数中包含的作用域。这是一个闭包。补充阅读:如果mailparser.on(“end”…)语句在client.listMessages(…)之前声明过呢,如何获取message.title和message.flags?假设在编码时其他地方出现了这种情况。如果它们可用,请从
mail\u对象
获取值。否则,添加另一个
end
侦听器作为闭包。如果
mail\u对象
中没有这些值,则可以调用从闭包中预定义的侦听器函数。
  // 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);

            });
  });