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

时间:2014-11-07 23:17:07

标签: javascript node.js

我有多个函数在收到/解析时用数据回调,我需要一次回调中的数据与另一次回调的数据匹配,这在不同的时间发生。

例如,我有以下代码使用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

    });
});

问题是控制台一个接一个地显示消息标题和标记,首先显示所有已解析的主体:

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 ...]

最终我会让这个应用程序将完整解析的消息(以及它们的解析标题)发送到数据库和浏览器,当我这样做时,我需要标记和其他元数据/标题与解析的主体配对,没有在回调中逻辑分隔。

Node.js中实现此目的的最佳做法是什么?什么是处理相同逻辑实体的单独回调的标准方法,有不同的方法来处理这个问题吗?

3 个答案:

答案 0 :(得分:2)

只需完成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
    });
});

这很容易,因为你的电话是嵌套的。有时您有多个异步操作,一旦完成,您就要执行操作。在这种情况下,请使用bluebird之类的承诺库并致电Promise.all()

答案 1 :(得分:1)

只需将显示主题的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(">>>---------------------------------------------------------");

答案 2 :(得分:0)

添加到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);

            });
  });