我如何使用 Q Promise 库来展平和降低下面代码片段的复杂性
How can I use Q Promise library to possibly flatten and reduce complexity of the snippet below
我是 NodeJS 的新手,正在学习 promise 库 Q。我最近想出了下面可怕的代码片段。我一辈子都想不出如何降低它的复杂性。我认为使用 promise 库应该可以帮助我做到这一点,但不确定如何去做。我在任何我认为需要指出每个步骤之间的依赖关系的地方发表评论。另请注意,
- 我正在使用 Node Express 库,这是一个 HTTP POST 处理程序
- 数据库查询使用节点-mysql库
- 我正在使用带有 --harmony 标志的 Node 并以 ECMA 6 为目标
- 函数 retrieveDeliveryAddress 和 retrieveMarkets return 承诺自己
请帮忙。
this.post = function(req, respond){
var deliveryAddressId = req.body.deliveryAddressId;
var restaurants = req.body.restaurants;
var previousToken = req.body.pricingToken;
//retrieveDeliveryAddress needs to be called initially to validate its existence before running any other queries
retrieveDeliveryAddress(deliveryAddressId)
.then(function(deliveryAddress){
var getConnectionFn = self.q.nbind(self.mainDataConnectionPool.getConnection, self.mainDataConnectionPool);
getConnectionFn().then((connection) => {
var retrievePricingItemsParamsQuery = self.config.data.queries.Q0014;
retrievePricingItemsParamsQuery.values = flattenRestaurantItemChoiceGroups(restaurants);
var queryFn = self.q.nbind(connection.query, connection);
queryFn(retrievePricingItemsParamsQuery)
.then(() => {
//Needs to be executed after the retrievePricingItemsParamsQuery since the next query uses a temp table created by it
var retrievePricingItemsQuery = self.config.data.queries.Q0015;
retrievePricingItemsQuery.values = [
self.config.sap.constants.defaultMandt,
self.config.sap.constants.trueFlag
];
queryFn(retrievePricingItemsQuery)
.then((resultsets) => {
var rows = self.helpersUtil.firstSqlResultset(resultsets);
if(rows == null) {
throw self.exceptionFac.createInstance('E1006', 409);
}
var result = {
items: [],
pricingToken: null,
pricingSummary: null
}
var itemGroups = self.lazy(rows).groupBy(function(x){
return x.RestaurantId + ':' + x.ItemId;
}).toArray();
//A bunch of other stuff happens here and finally I invoke the response callback with the result
result.pricingSummary = calculatePricingSummary(deliveryAddress, result.items);
respond(null, result);
}).catch((err) => {
respond(err, null);
connection.release();
}).done();
}).catch((err) => {
respond(err, null);
connection.release();
}).done();
}).catch((err) => {
respond(err, null);
}).done();
}).catch((err) => {
respond(err, null);
}).done();
};
答案已经在上面的评论中(@minitech, @laggingreflex),参考的文章解释得很好。所以这真的只是一个插图...
retrieveDeliveryAddress(deliveryAddressId)
.then(function(deliveryAddress){
var getConnectionFn = self.q.nbind(self.mainDataConnectionPool.getConnection, self.mainDataConnectionPool);
return getConnectionFn();
})
.then((connection) => {
var retrievePricingItemsParamsQuery = self.config.data.queries.Q0014;
retrievePricingItemsParamsQuery.values = flattenRestaurantItemChoiceGroups(restaurants);
var queryFn = self.q.nbind(connection.query, connection);
return queryFn(retrievePricingItemsParamsQuery).then(() => { return queryFn; });
})
.then((queryFn) => {
//Needs to be executed after the retrievePricingItemsParamsQuery since the next query uses a temp table created by it
var retrievePricingItemsQuery = self.config.data.queries.Q0015;
retrievePricingItemsQuery.values = [
self.config.sap.constants.defaultMandt,
self.config.sap.constants.trueFlag
];
return queryFn(retrievePricingItemsQuery);
})
.then((resultsets) => {
var rows = self.helpersUtil.firstSqlResultset(resultsets);
if(rows == null) {
throw self.exceptionFac.createInstance('E1006', 409);
}
var result = {
items: [],
pricingToken: null,
pricingSummary: null
}
var itemGroups = self.lazy(rows).groupBy(function(x){
return x.RestaurantId + ':' + x.ItemId;
}).toArray();
//A bunch of other stuff happens here and finally I invoke the response callback with the result
result.pricingSummary = calculatePricingSummary(deliveryAddress, result.items);
respond(null, result);
}).catch((err) => {
respond(err, null);
connection.release();
}).done();
我是 NodeJS 的新手,正在学习 promise 库 Q。我最近想出了下面可怕的代码片段。我一辈子都想不出如何降低它的复杂性。我认为使用 promise 库应该可以帮助我做到这一点,但不确定如何去做。我在任何我认为需要指出每个步骤之间的依赖关系的地方发表评论。另请注意,
- 我正在使用 Node Express 库,这是一个 HTTP POST 处理程序
- 数据库查询使用节点-mysql库
- 我正在使用带有 --harmony 标志的 Node 并以 ECMA 6 为目标
- 函数 retrieveDeliveryAddress 和 retrieveMarkets return 承诺自己
请帮忙。
this.post = function(req, respond){
var deliveryAddressId = req.body.deliveryAddressId;
var restaurants = req.body.restaurants;
var previousToken = req.body.pricingToken;
//retrieveDeliveryAddress needs to be called initially to validate its existence before running any other queries
retrieveDeliveryAddress(deliveryAddressId)
.then(function(deliveryAddress){
var getConnectionFn = self.q.nbind(self.mainDataConnectionPool.getConnection, self.mainDataConnectionPool);
getConnectionFn().then((connection) => {
var retrievePricingItemsParamsQuery = self.config.data.queries.Q0014;
retrievePricingItemsParamsQuery.values = flattenRestaurantItemChoiceGroups(restaurants);
var queryFn = self.q.nbind(connection.query, connection);
queryFn(retrievePricingItemsParamsQuery)
.then(() => {
//Needs to be executed after the retrievePricingItemsParamsQuery since the next query uses a temp table created by it
var retrievePricingItemsQuery = self.config.data.queries.Q0015;
retrievePricingItemsQuery.values = [
self.config.sap.constants.defaultMandt,
self.config.sap.constants.trueFlag
];
queryFn(retrievePricingItemsQuery)
.then((resultsets) => {
var rows = self.helpersUtil.firstSqlResultset(resultsets);
if(rows == null) {
throw self.exceptionFac.createInstance('E1006', 409);
}
var result = {
items: [],
pricingToken: null,
pricingSummary: null
}
var itemGroups = self.lazy(rows).groupBy(function(x){
return x.RestaurantId + ':' + x.ItemId;
}).toArray();
//A bunch of other stuff happens here and finally I invoke the response callback with the result
result.pricingSummary = calculatePricingSummary(deliveryAddress, result.items);
respond(null, result);
}).catch((err) => {
respond(err, null);
connection.release();
}).done();
}).catch((err) => {
respond(err, null);
connection.release();
}).done();
}).catch((err) => {
respond(err, null);
}).done();
}).catch((err) => {
respond(err, null);
}).done();
};
答案已经在上面的评论中(@minitech, @laggingreflex),参考的文章解释得很好。所以这真的只是一个插图...
retrieveDeliveryAddress(deliveryAddressId)
.then(function(deliveryAddress){
var getConnectionFn = self.q.nbind(self.mainDataConnectionPool.getConnection, self.mainDataConnectionPool);
return getConnectionFn();
})
.then((connection) => {
var retrievePricingItemsParamsQuery = self.config.data.queries.Q0014;
retrievePricingItemsParamsQuery.values = flattenRestaurantItemChoiceGroups(restaurants);
var queryFn = self.q.nbind(connection.query, connection);
return queryFn(retrievePricingItemsParamsQuery).then(() => { return queryFn; });
})
.then((queryFn) => {
//Needs to be executed after the retrievePricingItemsParamsQuery since the next query uses a temp table created by it
var retrievePricingItemsQuery = self.config.data.queries.Q0015;
retrievePricingItemsQuery.values = [
self.config.sap.constants.defaultMandt,
self.config.sap.constants.trueFlag
];
return queryFn(retrievePricingItemsQuery);
})
.then((resultsets) => {
var rows = self.helpersUtil.firstSqlResultset(resultsets);
if(rows == null) {
throw self.exceptionFac.createInstance('E1006', 409);
}
var result = {
items: [],
pricingToken: null,
pricingSummary: null
}
var itemGroups = self.lazy(rows).groupBy(function(x){
return x.RestaurantId + ':' + x.ItemId;
}).toArray();
//A bunch of other stuff happens here and finally I invoke the response callback with the result
result.pricingSummary = calculatePricingSummary(deliveryAddress, result.items);
respond(null, result);
}).catch((err) => {
respond(err, null);
connection.release();
}).done();