Node.js 如何从一个回调函数到另一个回调函数获取变量?
好的,假设我有两个带回调的侦听器,其中一个回调中的代码依赖于另一个回调中的变量uidFromonedFunction 例如:Node.js 如何从一个回调函数到另一个回调函数获取变量?,node.js,promise,Node.js,Promise,好的,假设我有两个带回调的侦听器,其中一个回调中的代码依赖于另一个回调中的变量uidFromonedFunction 例如: //using andris9/mailparser on github var mailparser = new MailParser({ streamAttachments: true } // OnEnd Function mailparser.on("end", function(objMail){ **UIDfromOnEndFuntion*
//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.onattachment中的回调获取变量UIDfromOnEndFunction
这是否涉及承诺?如何实现这一点?您可以通过闭包实现这一点:只需从外部访问变量即可
//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的评论。如果他们不以这种方式开火,这根本是不可能的。好的,我想出了一个解决方案。它基于@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,例如,结束一次,您可以根据这些知识触发一个函数,就像我通过调用FuncBotHendandAttachmentCommitted所做的那样
我认为这需要被清理并做成一个图书馆,除非有更好的方法来做到这一点。如果您知道更好的解决方案,请发表意见,否则我可能会继续为此解决方案编写库
我认为另一个可行的解决方案是将mailparser.onceattachment。。。在mailparser.onceend的回调内部。。。但我怀疑,如果首先发出附件,那么这种解决方案就不起作用了。如果出于某种原因处理许多不同的发出事件,或者不同的对象发出不同的事件,那么与基于库的解决方案相比,这种解决方案似乎有点笨拙 从根本上讲,问题在于假设在附件之前触发编辑。如果在附件之后调用end,我可以这样认为,但我不建议这样做。我需要一个解决方案,可以处理侦听器的end和附件,以任意返回顺序;这就是我问这个问题的原因。@blueuser从根本上违背了异步回调的思想,因为您希望以同步方式处理它们:您唯一的选择是等到变量发生更改。承诺可以用来实现这一点吗?你知道吗?例如,承诺似乎被用来按顺序将异步请求链接在一起。也许承诺+结束?@blueuser我在承诺方面做的工作还不够多,无法明确回答这个问题,但也许能帮你解决这个问题。