sails.js bluebird承诺链接多个查询慢

时间:2016-02-04 18:39:50

标签: javascript node.js promise sails.js bluebird

我是node.js / sails.js的新手。我听说node.js非常快。但是我的表现非常糟糕。在这里,我使用蓝鸟作为诺言。基本上我想重构它,所以它会更快。在这里,我正在执行四个不同的查询,以获取产品详细信息(名称,型号,描述等),产品附加图像,产品选项和每个选项详细信息。

我想知道如何将这四个查询拆分为四种不同的方法或函数,以便我可以在以后再次使用它们,当我将调用get getProductdetails时,这将调用所有四个查询并更快地获得最终结果。请帮帮我。我被迫继续前进。非常感谢提前。

\def\desc #1\}\{#2 {\textcolor{red}{\textbf{#1}} \emph{#2}}

1 个答案:

答案 0 :(得分:1)

节点是"快速"对于某些工作负载和模式。它的很多速度来自于它处理IO和网络任务(例如数据库查询)的方式,这增加了它处理规模的能力。 [如果您有兴趣阅读有关它的更多内容及其工作原理,请参阅事件循环 - here是一篇好文章]

就改进你提供的代码而言 - 我假设你使用Bluebird并安装了Underscore.js以使它更整洁。出于安全考虑,我强烈建议您切换到ORM或至少确保您在SQL查询中转义信息。节点很快但不能解决注入问题:)

我重构了你的代码,以便请求可以并行执行,这有助于通过利用任何其他语言的并发来加速代码。我已经使用了promises并且还利用了bluebird promisify所有系统,因此你不需要创建一个Promise。

var promisifiedProduct = Promise.promisifyAll(Product)
var _ = require('underscore')

getProductDetails: function(product_id) {

    var details_retriever = promisifiedProduct.queryAsync("select * from product p, product_description pd where p.product_id=" + product_id + " and pd.product_id= p.product_id and pd.language_id=1")

    var images_retriever = promisifiedProduct.queryAsync("SELECT * FROM product_image WHERE product_id = " + product_id + " ORDER BY sort_order ASC")

    var options_retriever = promisifiedProduct.queryAsync("SELECT * FROM product_option po LEFT JOIN `option` o ON (po.option_id = o.option_id) LEFT JOIN option_description od ON (o.option_id = od.option_id) WHERE po.product_id = " + product_id + " AND od.language_id = '1' ORDER BY o.sort_order")

    // Iterate over each option for some additional information
    var sub_options_retriever = options_retriever.then(function(options) {

        // Map the options to a Promise that will resolve to the value
        var sub_option_retrievers = _.map(options, function (option) {

            // Return a Promise that resolves to the desired object
            return  promisifiedProduct.queryAsync("SELECT * FROM product_option_value pov LEFT JOIN option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_id = " + product_id + " AND pov.product_option_id = " + option.product_option_id + " AND ovd.language_id = '1' ORDER BY ov.sort_order")
                .then(function(sub_options) {

                    return {
                        options: option, 
                        option_value: sub_options
                    }

                })

        })

        // Concurrently retrieve the sub options
        return Promisify.all(sub_option_retrievers)

    })

    // Wait for all the information to be retrieved
    var retriever = Promisify.all([details_retriever, images_retriever, options_retriever, sub_option_retriever])

    var result_formatter = retriever.then(function(results) {

        // Create a scope level variable for options so we are not mutating a provided argument
        var options = results[2]

        // Add each sub_option into options - Not sure why?
        var formatted_options = _.forEach(result[3], function(sub_option) {
            options.push(sub_option)
        })

        return {
            details: results[0][0],
            options: formatted_options, 
            images: results[1]
        }
    })

    return result_formatter
}

我还没有对代码进行测试或对任何功能进行双重检查,因此可能需要稍微调整一下,但这应该是好的!