优化自定义API

时间:2015-01-24 15:08:43

标签: node.js azure azure-mobile-services

我正在使用Node.js作为后端的Azure移动服务,因为它的本质,我很难处理它的超时情况:



var Dict = require("collections/dict");
var q = require('q');
var async = require('async');

exports.post = function(request, response) {
    console.log('body : ' + request.body);
    mssql = request.service.mssql;
    tables = request.service.tables;
    //Get payload from request body
    // extracted parameters;

    var processRecords;
    
    var sp = new Dict();
    getA(longitude, latitude)
        .then(function(results) {
            async.each(results,
                function(value, callback) {
                    var zc = value.zc;
                    var c = value.c;

                    processRecord(zc, c)
                        .then(function(record) {
                            sp.add({
                                zc: zc,
                                c: c,
                                B: record[0],
                                C: record[1],
                                D: record[2],
                                E: record[3],
                                F: record[4],
                                G: record[5]
                            }, zc);
                            
                            callback();
                        })
                        .catch(function(err) {
                            console.log("error is: " + err);
                            callback(err);
                        });
                },
                function(err) {
                    if (err) {
                        response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
                    } else {
                        response.send(statusCodes.OK, sp.values());
                    }
                });
        })
        .catch(function(err) {
            response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
        });
}

function processRecord(zc,c) {
    return q.all([
         getB(zc)
        ,getC(c)
        ,getD(zc)
        ,getE(zc,c)
        ,getF(zc,c)
        ,getG(zc,c)
    ]);
}

function getA(longitude, latitude) {
    var deferred = q.defer();
    var sql = "a query from table function";
    mssql.query(sql, [longitude, latitude/*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getB(zc) {
    var deferred = q.defer();
    var sql = " a queryy ";
    mssql.query(sql, [zc, /*some param*/ ], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getC(c) {
    var deferred = q.defer();
    var sql = "query";
    mssql.query(sql, [c /*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getD(zc) {
    var deferred = q.defer();
    var sql = "query";
    mssql.query(sql, [zc /*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getE(zc, c) {
    var deferred = q.defer();
    var sql = "query";
    mssql.query(sql, [zc,c /*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getF(zc, c) {
    var deferred = q.defer();
    var sql = "query";
    mssql.query(sql, [zc, c /*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}

function getG(zc, c) {
    var deferred = q.defer();
    var sql = "query";
    mssql.query(sql, [zc, c /*some param*/], {
        success: function(results) {
            deferred.resolve(results);
        },
        error: function(err) {
            deferred.reject(err);
        }
    });
    return deferred.promise;
}




现在它是相当数据密集型的Custom API。我从getA()得到的结果从2到200不等,我希望你的建议能减少这些数据。

我已经考虑过改善它的一些事情,让我知道你的想法:

  1. 限制getA()函数的结果
  2. 在SQL Server中创建一个表值函数,以根据我从客户端收到的过滤器获取所有数据。
  3. 但是上面的每一个都有一个缺点:

    例如,使用第一个选项,我将能够获得所需的结果,就像我必须给客户端至少10个最佳位置而getA()函数可能会返回10但是当我在这些记录上进一步过滤它没有&# 39;没有任何好结果。

    表值函数选项可能会给我提供性能,但它不会返回我可以立即返回给用户的数据。正确的数据结构良好:

    {   zc:...,   C:...,   B:[],   ...   ...
    }

    请给我任何指示。

    谢谢, Attiqe

    P.S:为了发布问题,我给出的所有功能名称都是虚构的。

1 个答案:

答案 0 :(得分:0)

因此,经过一些脑力激荡,我创建了一个表值函数,现在正在处理所有查询并返回我的表,我将它发送回客户端。有了这个,我把它从30秒+响应减少到5秒以下。



exports.post = function(request, response) {
    console.log('body : ' + request.body);
    mssql = request.service.mssql;
    tables = request.service.tables;
    //Get filters from request body
    var latitude = request.body.latitude;
    var longitude = request.body.longitude;
    
    
    getResults(longitude, latitude, offset)
        .then(function(results) {
            response.send(statusCodes.OK, results);
        })
        .catch(function(err) {
            console.log("error is: " + err);
            response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
        });
}

function getResults(longitude, latitude, offset) {
    var deferred = q.defer();
    var sql = "SELECT * FROM [GetResults] (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
    mssql.query(sql, [latitude, longitude /*more param*/], {
        success: function(results) {
            console.log("count: " + results.length);
            deferred.resolve(results);
        },
        error: function(err) {
            console.log("error is: " + err);
            deferred.reject(err);
        }
    });
    return deferred.promise;
}




谢谢, Attiqe