求大神帮忙解决个嵌套跟循环查询数据库导致代码太乱的问题 Nodejs

求大神帮忙解决个嵌套跟循环查询数据库导致代码太乱的问题 Nodejs

项目用的nodejs来做 遇到一个问题求大神帮忙 查用户信息的时候因为要同时查询好几张表,所以就需要一次执行多个sql语句,这样就需要很多个嵌套函数了,还有最重要就是因为需要根据表中的每一条数据来查出相对应的数据,所以需要写出个循环来依次迭代查出的数据,并进行数据查询,实现方式 就是加了嵌套跟加了状态控制,功能虽然实现了,但是代码真是惨不忍睹!!贴出代码 dbService.psQuery(sql, [userId], function (rows) { user.userInfo = rows[0]; sql = sqls[‘user’][‘getUserPageShowList’][‘sql’]; dbService.psQuery(sql, [userId], function (rows) { user.playerList = rows; sql = sqls[‘user’][‘getUserPageActionList’][‘sql’]; /获取用户的动态信息/ dbService.psQuery(sql, [userId], function (rows) { sql = sqls[‘action’][‘getActionImgById’][‘sql’]; var lock = 0; for (var i = 0; i < rows.length; i++) { /根据动态信息来获取动态中的图集信息/ dbService.psQuery(sql, rows[i].ACTIONID, function (imgList) { if (imgList && imgList.length > 0) { rows[lock].imgList = imgList; } else { rows[lock].imgList = {}; } lock++; if (lock >= rows.length) { user.actionList = rows; /获取用户的图集信息/ sql = sqls[‘user’][‘getUserPageAlbumList’][‘sql’]; dbService.psQuery(sql, [userId], function (rows) { sql = sqls[‘album’][‘getAlbumImgById’][‘sql’]; var lock = 0; for (var i = 0; i < rows.length; i++) { dbService.psQuery(sql, rows[i].ALBUMID, function (imgList) { if (imgList && imgList.length > 0) { rows[lock].imgList = imgList; } else { rows[lock].imgList = {}; } lock++; if (lock >= rows.length) { user.albumList = rows; fn(user); } }); } });

                    }
                });
            }
        });
    });
});

小弟一直是做java开发的 刚学node 想想如果是同步执行的话的就简单多了吧 希望在大神们帮个忙能出个更好办法让这些代码解脱了啊


9 回复

要解决嵌套和循环查询数据库导致代码混乱的问题,可以考虑使用异步控制流库(如 asyncpromise),或者利用现代 JavaScript 的 async/await 语法。以下是一个使用 async/awaitPromise 来简化代码的例子:

示例代码

const dbService = require('./dbService'); // 假设这是你的数据库服务模块

async function getUserInfo(userId) {
    try {
        const user = {};

        // 查询用户基本信息
        user.userInfo = await new Promise((resolve, reject) => {
            dbService.psQuery(sqls['user']['getUserInfo']['sql'], [userId], (rows) => resolve(rows[0]));
        });

        // 获取用户页面显示列表
        user.playerList = await new Promise((resolve, reject) => {
            dbService.psQuery(sqls['user']['getUserPageShowList']['sql'], [userId], (rows) => resolve(rows));
        });

        // 获取用户的动态信息
        user.actionList = await getActionList(userId);

        // 获取用户的图集信息
        user.albumList = await getAlbumList(userId);

        return user;
    } catch (error) {
        console.error('Error fetching user info:', error);
        throw error;
    }
}

async function getActionList(userId) {
    const actionList = await new Promise((resolve, reject) => {
        dbService.psQuery(sqls['user']['getUserPageActionList']['sql'], [userId], (rows) => resolve(rows));
    });

    const actionPromises = actionList.map(async (action) => {
        const imgList = await new Promise((resolve, reject) => {
            dbService.psQuery(sqls['action']['getActionImgById']['sql'], [action.ACTIONID], (imgList) => resolve(imgList));
        });
        return { ...action, imgList };
    });

    return Promise.all(actionPromises);
}

async function getAlbumList(userId) {
    const albumList = await new Promise((resolve, reject) => {
        dbService.psQuery(sqls['user']['getUserPageAlbumList']['sql'], [userId], (rows) => resolve(rows));
    });

    const albumPromises = albumList.map(async (album) => {
        const imgList = await new Promise((resolve, reject) => {
            dbService.psQuery(sqls['album']['getAlbumImgById']['sql'], [album.ALBUMID], (imgList) => resolve(imgList));
        });
        return { ...album, imgList };
    });

    return Promise.all(albumPromises);
}

// 使用 async/await 调用
async function main() {
    try {
        const userId = 'someUserId';
        const userInfo = await getUserInfo(userId);
        console.log(userInfo);
    } catch (error) {
        console.error('Failed to fetch user info:', error);
    }
}

main();

解释

  1. getUserInfo 函数

    • 使用 async/await 来处理每个数据库查询。
    • 每个查询都返回一个 Promise,使用 await 等待结果。
  2. getActionListgetAlbumList 函数

    • 这两个函数分别处理动态信息和图集信息的查询。
    • 使用 map 方法生成一系列 Promise,然后通过 Promise.all 并行处理这些 Promise
  3. main 函数

    • 使用 async/await 来调用 getUserInfo 函数,并打印结果。

这种方式不仅使代码更加清晰易读,而且提高了代码的可维护性和可扩展性。


async bluebird Q

不用异步,换同步不就行了。

问题 nodejs mysql的查询就是事件驱动的
connection.query(sql, values, function (err, rows) { if (err)throw err; fn(rows); }); 有同步查询的么

async.waterfall([ function(callback){ dbService.psQuery(sql, [userId], callback); }, function(rows, callback){ … dbService.psQuery(sql, [userId], callback) }, function(rows, callback){ … dbService.psQuery(sql, [userId], callback); }, function(rpws, callback){
async.forEach(rows, function(next){ async.waterfall([function(cb){ dbService.psQuery(sql, rows[i].ACTIONID,cb) }, function(imageList, cb){ … dbService.psQuery(sql, [userId], cb); }, function(imageList, cb){ … async.forEach(rows, function(next2){ dbService.psQuery(sql, rows[i].ALBUMID, function (imgList) { … next2(); }); },function(err){ cb(); }) }],function(err, results){ next(); });

       }, function(err, results){
             callback();
       })

], function (err, result) { fn(user); });

你妹,你不能写成一条SQL么?使用多结果集一次查询就能搞定了……

var eventproxy = require('eventproxy');

可以噢,北漂吧,帝都Noder待遇不错的!

你的问题可以通过使用 async/await 和 Promise 来简化代码逻辑。以下是改进后的代码示例:

const dbService = require('./dbService'); // 引入你的数据库服务模块

async function getUserInfo(userId) {
  try {
    const [userInfo] = await dbService.psQuery(sqls['user']['getUserInfo']['sql'], [userId]);
    const userPageShowList = await dbService.psQuery(sqls['user']['getUserPageShowList']['sql'], [userId]);
    const userPageActionList = await dbService.psQuery(sqls['user']['getUserPageActionList']['sql'], [userId]);

    for (let action of userPageActionList) {
      action.imgList = await dbService.psQuery(sqls['action']['getActionImgById']['sql'], [action.ACTIONID]);
    }

    const userPageAlbumList = await dbService.psQuery(sqls['user']['getUserPageAlbumList']['sql'], [userId]);

    for (let album of userPageAlbumList) {
      album.imgList = await dbService.psQuery(sqls['album']['getAlbumImgById']['sql'], [album.ALBUMID]);
    }

    return {
      userInfo,
      userPageShowList,
      userPageActionList,
      userPageAlbumList,
    };
  } catch (error) {
    console.error(error);
  }
}

// 调用函数
getUserInfo(userId)
  .then(user => {
    fn(user);
  })
  .catch(error => {
    console.error('Error:', error);
  });

通过这种方式,你可以避免嵌套回调,使代码更清晰、易读。每个异步操作都用 await 等待完成,然后继续执行后续代码。

回到顶部