我如何使用 Q Promise 库来展平和降低下面代码片段的复杂性

How can I use Q Promise library to possibly flatten and reduce complexity of the snippet below

我是 NodeJS 的新手,正在学习 promise 库 Q。我最近想出了下面可怕的代码片段。我一辈子都想不出如何降低它的复杂性。我认为使用 promise 库应该可以帮助我做到这一点,但不确定如何去做。我在任何我认为需要指出每个步骤之间的依赖关系的地方发表评论。另请注意,

  1. 我正在使用 Node Express 库,这是一个 HTTP POST 处理程序
  2. 数据库查询使用节点-mysql库
  3. 我正在使用带有 --harmony 标志的 Node 并以 ECMA 6 为目标
  4. 函数 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();