考虑到以下代码,我有以下问题:
#1 这些bluebird.all函数返回的值需要在以后的函数中访问。从我读过的内容中我也可以使用this-context,而无需在之前声明变量。但是我在嵌套函数中访问这些值时遇到了一些问题。
#2 是为了在后续功能中使这些参数可以访问的方式?
#3 由于这些函数只在main方法中工作,它们是否应该像这样嵌套?
#4 我找不到有条件的承诺链执行的更好的解决方案。如果有的话,我更喜欢一个不那么详细的解决方案。
#5 作为#3,但这次嵌套在嵌套函数中。
function create(contactRequestPayload) {
// #1 Local variables vs this
var
contactRequest = {},
property = {};
return bluebird.all([
new ContactRequestModel(contactRequestPayload).save(),
getPropertyById(contactRequestPayload.propertyId),
sendContactMail()
])
// #2 Correct usage of spread
.spread(function (_contactRequest, _property) {
contactRequest = _contactRequest;
property = _property;
})
.then(processFeedbackEmail)
.then(updateModelState)
.then(returnContactRequest)
.catch(errorHandler);
// #3 Nested functions
function processFeedbackEmail() {
// #4 Conditional code execution
if (!_.get(property, "contact.email.feedback")) {
return bluebird.resolve();
}
return createFeedbackObject()
.then(convertToXml)
.then(sendFeedbackMail)
.catch(function (error) {
logger.warn(error);
});
// #5 Nested functions within a nested function
function createFeedbackObject() {
return contactRequestFeedbackObjectService.from(property, contactRequest);
}
function convertToXml(contactFeedbackObject) {
contactRequest.feedbackJson = contactFeedbackObject;
return objectToXmlService.convert(contactFeedbackObject);
}
function sendFeedbackMail(contactFeedbackXml) {
contactRequest.feedbackXml = contactFeedbackXml;
return contactRequestFeedbackMailService.send(property.contact.email.feedback, contactFeedbackXml);
}
}
function returnContactRequest() {
return contactRequest;
}
function sendContactMail() {
return searchServiceClient.sendContactMail(contactRequestPayload);
}
function getPropertyById(propertyId) {
return getPropertyServiceClient().fetchPropertyById(propertyId);
}
function updateModelState() {
contactRequest.state = 'SENT';
return contactRequest.save();
}
}
答案 0 :(得分:2)
Promise-chains让我们按照同步代码的顺序对事物进行排序。我发现内联函数重新获得了重要的背景。要使用以前的变量,我使用旧的缩进:
function create(contactRequestPayload) {
return bluebird.all([
new ContactRequestModel(contactRequestPayload).save(),
getPropertyServiceClient().fetchPropertyById(contactRequestPayload.propertyId),
searchServiceClient.sendContactMail(contactRequestPayload)
])
.spread(function processFeedbackEmail(contactRequest, property) {
if (_.get(property, "contact.email.feedback")) {
return contactRequestFeedbackObjectService.from(property, contactRequest)
.then(function convertToXml(feedback) {
contactRequest.feedbackJson = feedback;
return objectToXmlService.convert(feedback);
})
.then(function sendFeedbackMail(xml) {
contactRequest.feedbackXml = xml;
return CRFeedbackMailService.send(property.contact.email.feedback, xml);
})
.catch(function (error) {
logger.warn(error);
});
}
})
.then(function updateModelState() {
contactRequest.state = 'SENT';
return contactRequest.save();
})
.then(function returnContactRequest() {
return contactRequest;
})
.catch(errorHandler);
}
(函数名称当然是可选的,但我保留了它们以供参考。)
对于条件,我将其反转,因为返回undefined
等于bluebird.resolve()
。
有些人可能认为这是一个风格问题,但ES7将这个类比归结为其自然结论:
async function create(contactRequestPayload) {
var [ contactRequest, property ] = await Promise.all([
new ContactRequestModel(contactRequestPayload).save(),
getPropertyServiceClient().fetchPropertyById(contactRequestPayload.propertyId),
searchServiceClient.sendContactMail(contactRequestPayload)
]);
if (_.get(property, "contact.email.feedback")) {
try {
var feedback = await contactRequestFeedbackObjectService.from(property,
contactRequest);
contactRequest.feedbackJson = feedback;
contactRequest.feedbackXml = await objectToXmlService.convert(feedback);
await CRFeedbackMailService.send(property.contact.email.feedback, xml);
} catch (error) {
logger.warn(error);
}
}
contactRequest.state = 'SENT';
await contactRequest.save();
return contactRequest;
}