如何将变量从一个回调变为另一个回调?

时间:2014-12-05 06:24:51

标签: node.js promise

好的,我说有两个带回调的监听器,一个回调中的代码取决于另一个回调的变量(UIDfromOnEndFunction)。

例如:

//using andris9/mailparser on github

var mailparser = new MailParser({
    streamAttachments: true
}

// OnEnd Function
mailparser.on("end", function(objMail){
    **UIDfromOnEndFuntion** = objMail.UID;

    saveToDB("mail" + "1234", objMail);
});


mailparser.on("attachment", function(attachment){
    var output = fs.createWriteStream("attachments/"
        + **UIDfromOnEndFuntion** + "/" + attachment.generatedFileName);
        // need UIDfromOnEndFunction here

    attachment.stream.pipe(output);
});

如何使mailparser.on("attachment"中的回调获取变量UIDfromOnEndFunction

这是否涉及承诺?你是怎么做到的?

2 个答案:

答案 0 :(得分:0)

您可以通过闭包执行此操作:只需从外部访问变量。

//using andris9/mailparser on github
var UIDfromOnEndFunction;

var mailparser = new MailParser({
    streamAttachments: true
}

// OnEnd Function
mailparser.on("end", function(objMail){
    UIDfromOnEndFuntion = objMail.UID;

    saveToDB("mail" + "1234", objMail);
});


mailparser.on("attachment", function(attachment){
    var output = fs.createWriteStream("attachments/" + UIDfromOnEndFuntion + "/" + attachment.generatedFileName);

    attachment.stream.pipe(output);
});

请注意我关于在end之前调用attachment的评论。如果他们不以这种方式开火,那么根本就不可能

答案 1 :(得分:0)

好的我想出了一个解决方案。它基于@Brenden Ashworth建议的封闭。这是未经测试但我相当肯定它会起作用,我想在我继续之前发布这个,因为我发现我不需要做原始问题所描述的以使我的项目工作。

但是,我仍然认为有必要解决这类问题是有用的,并且我不知道更好的解决方案。

这是我的解决方案:

//using andris9/mailparser on github

var mailparser = new MailParser({
    streamAttachments: true
}

var UIDfromOnEndFuntion;
var myAttachment;
var intNumberOfEmitsToEndAndAttachment = 0;


var funcBothEndAndAttachmentEmitted = function () {
    var output = fs.createWriteStream("attachments/"
        + UIDfromOnEndFuntion + "/" + myAttachment.generatedFileName);
            //UIDfromEndFunction should be garaunteed to be
            //populated by .once("end",...)

    myAttachment.stream.pipe(output);
        //myAttachment should be gauranteed to be populated
        //by .once("attachment",...)
}

mailparser.once("end", function(objMail){
    UIDfromOnEndFuntion = objMail.UID;

    saveToDB("mail" + "1234", objMail);

    intNumberOfEmitsToEndAndAttachment++;
    if (intNumberOfEmitsToEndAndAttachment == 2) {
        funcBothEndAndAttachmentEmitted();
    }
});


mailparser.once("attachment", function(attachment){
    myAttachment = attachment;

    intNumberOfEmitsToEndAndAttachment++;
    if (intNumberOfEmitsToEndAndAttachment == 2) {
        funcBothEndAndAttachmentEmitted();
    }
});

现在这只适用于单个发出的“结束”和单个发出的“附件”。

您可以通过跟踪如何处理多个附件来获得更多创意。例如,不是使用整数来跟踪调用的总数,而是可以使用像[{"attachment",attachment_args1},{"attachment",attachment_args2},{"end",end_args2}]这样的对象数组来跟踪调用(这意味着attachment已被调用两次到目前为止,例如,"end"一次,您可以通过调用funcBothEndAndAttachmentEmitted()来触发基于该知识的函数。

我认为这需要清理并制作成一个库,除非有更好的方法来做到这一点并不明显。 (如果您知道更好的解决方案,请发表评论,或者我可以继续为此解决方案编写库。)

我认为可能有用的另一个解决方案是将mailparser.once("attachment"...)放在mailparser.once("end"...)的回调中,但我怀疑如果首先发出"attachment"则不起作用,这个解决方案似乎如果由于某种原因处理许多不同的发射事件或发出不同事件的不同对象,则与基于库的解决方案相比,有点笨拙。