Node JS如何获取外部的查询数据

时间:2015-08-04 13:03:39

标签: javascript php node.js express

我是Node js的新手,我正在尝试最近几天实现此功能,但我无法修复

103,202,234,260,301,324,356,379,405,412,421,284,137,439,315,150,322,454,185,335,481,208,495,223,358,258,522,267,365,526,
536,374,399,566,580,424,302,602,335,365,618,441,380,455,397,483,510,410,419,622,529,534,633,442,544,568,653,668,474,502,
689,583,607,694,699,530,618,648,654,555,705,723,563,738,672,595,746,697,766,720,624,740,794,798,818,845,859,653,752,758,
783,674,793,805,876,831,892,918,929,689,865,950,874,966,997,716,738,899,759,1023,1032,917,1053,938,944,1080,771,797,
960,1089,980,815,839,850,1110,1011,1115,861,878,1143,901,1025,931,1175,1192,1197,1050,1229,959,988,1058,1008,1038,1088,
1116,1126,1135,1063,1256,1269,1082,1275,1088,1305,1122,1154,1157,1326,1184,1350,1184,1205,1236,1268,1293,1324,1373,1347,
1365,1217,1400,1240,1261,1414,1381,1406,1413,1443,1282,1451,1456,1442,1476,1485,1475,1488,1499,1510,1508,1316,1325,1338,
1540,1536,1353,1556,1558,1588,1363,1587,1617,1382,1625,1402,1609,1415,1633,1642,1655,1671,1689,1697,1439,1712,1458,1732,
1481,1693,1510,1747,1715,1762,1730,1791,1820,1522,1539,1748,1759,1566,1577,1584,1611,1646,1834,1790,1653,1820,1659,1833,
1693,1842,1704,1717,1846,1868,1729,1744,1773,1882,1796,1915,1937,1814,1861,1846,1941,1871,1905,1893,1931,1945,1917,
1960,1979,1941,1960,1980,1933,1962,2014,2046,1975,1988,2008,1988,2040,1995,2062,2000,2009,2025,2083,2058,2067,2083,2103,
2038,2114,2121,2134,2063,2166,2115,2124,2178,2202,2135,2090,2104

我还有一个查询?在节点js中:如果表具有用户,则用户具有不同的关系表,如订单,配置文件,地址

如何实现此

首先我得到了用户 用户循环
获取每个用户的个人资料,地址,订单
最终用户循环

但是上面的场景我无法在节点js中实现,但在php中非常简单,就像这样

exports.get_exercises_for_trainer = function(req, res)
    {

                connection.query('SELECT * FROM ag_exercise', function(err, exercise)
                 {


                    console.log('------------------------------before add fields ----------------------------------');
                    console.log(exercise);

                    for (var i in exercise)
                  {

                        fields(exercise[i].wt_id, function(result1) {


                                    exercise[i].wt_fields = result1; //here i am adding result set of other query but i am not geting this fields data

                                    console.log(result1) //but i printed here working fine but i need this result1 data out side query 

                          });

                    }

                    console.log('------------------------------after add fields ----------------------------------');
                    console.log(exercise);
                    res.render('pages/trainer_home.ejs',{page_title:"Exercise Create",exercise:exercise});

                    });


          }

        function fields(wt_id,callback) 
        {
            connection.query('SELECT *  FROM ag_workout_type_fields  WHERE wt_id = "'+wt_id+'"', function( err1, result1){

                  callback(result1);

             });

             }

1 个答案:

答案 0 :(得分:2)

这里有三个主要问题,我将分别加分。

问题1:在制作异步功能时,如何在该功能之外访问我的数据?

来自异步调用的所有数据都是通过回调,事件监听器或promises(一个花哨的回调和事件监听器处理程序)来访问的。在大多数情况下,您将只使用回调。所以,而不是:

get_user = function(user_id){
    //Do some stuff to get the user
    return the_user;
};
var user = get_user('1234');
//do whatever you want with user

你会看到:

get_user = function(user_id,callback){
    //Do some stuff to get the user
    callback(null,the_user);
}
get_user('1234',function(err,user){
    //do whatever you want with user
});

当我们进入问题3时,您将看到更复杂的用例。

问题2:如何循环访问我的数据,对每一行执行子查询,并将该数据附加到我当前的数据?

这里有几个问题。

  1. 每次查询数据库时,都在执行异步功能,因此需要相应地管理所有这些回调。幸运的是,有一些很棒的工具可以帮助你,我们将使用异步。
  2. 每次在for循环中调用异步函数时,for循环都会继续,因此你的迭代器会被覆盖,但你的异步函数还没有完成,所以你会得到各种意想不到的结果,比如消失变量,或错过映射的结果。您可以使用JavaScript闭包来处理这个问题,或者,您可以再次依赖像async这样的库来处理它。
  3. 我们不会在查询结果上运行for循环,而是将其传递给async.forEachOf,我们将使用它来修改现有数组,并将后续查询的结果附加到主查询的行。请务必注意,forEachOf将并行运行后续查询,因此您不应使用单个数据库连接,而应使用池。如果必须使用单个数据库连接,请改用forEachOfSeries。

    async = require('async');
    exports.get_exercises_for_trainer = function(req, res){
        connection.query('SELECT * FROM ag_exercise', function(err, exercises)
        {
            console.log('------------------------------before add fields ----------------------------------');
            console.log(exercises);
            async.forEachOf(exercises,function(exercise,index,callback){
                connection.query('SELECT * FROM ag_workout_type_fields WHERE wt_id = "' + exercise.wt_id + '"', function( err, result1){
                    if(err)return callback(err1);
                    exercises[index].wt_fields = result1; //Modify original array
                    return callback();
                });
            },function(err){
                if(err){return;} //do some error handling
                console.log('------------------------------after add fields ----------------------------------');
                console.log(exercises);
                res.render('pages/trainer_home.ejs',{page_title:"Exercise Create",exercise:exercises});
            });
        });
    };
    

    问题3:如何执行许多相关但不同的查询,以便我可以填充有关我的对象的信息?

    这是异步库的另一个很好的用法。在这种情况下,由于查询都不同,我们将使用parallel而不是forEachOf。

    async = require('async');
    populate_user = function(user,_callback){
        async.paralell({
            profile: function(callback){
                var sql = "SELECT * FROM profiles WHERE user_id = " + user.id + " LIMIT 1 ";
                var connection.query(sql,function(err,rows,fields){
                    if(err)return callback(err);
                    if(rows.length === 1)return callback(null,rows[0]);
                    return callback(null,[]);
                });
            },
            address: function(callback){
                var sql = "SELECT * FROM addresses WHERE user_id = " + user.id + " LIMIT 1 ";
                var connection.query(sql,function(err,rows,fields){
                    if(err)return callback(err);
                    if(rows.length === 1)return callback(null,rows[0]);
                    return callback(null,[]);
                });
            },
            orders: function(callback){
                var sql = "SELECT * FROM orders WHERE user_id = " + user.id;
                var connection.query(sql,function(err,rows,fields){
                    if(err)return callback(err);
                    if(rows.length > 0)return callback(null,rows); //notice how this one could have multiple results so we're returning them all
                    return callback(null,[]);
                });
            },
        },
        function(err,result){
            if(err)return _callback(err);
            for(var att in result){user[att] = result[att];}
            callback(null,user);
        }
    }
    user = {id:1234};
    populate_user(user,function(err,populated_user)){
        console.log(user); //wow notice how it's populated too!
        console.log(populated_user); //this is really just a new handle for the same object
    });
    

    我想要注意的是,没有对此进行测试,甚至没有测试语法,因此可能需要稍微改动。