再次将单独的异步分支重新放回一个分支

时间:2017-10-12 05:52:20

标签: mysql node.js callback

我正在开发一个使用express和mysql库的节点js app。

我有一个MySQL用户表,其中包含以下列:

  • 自动递增主ID
  • username varchar unique

没有密码等。

其他表格包括:

  • ID
  • ROOM_NAME

user_room

  • ID
  • user_id(FK到用户表)
  • room_id(FK到房间桌)

细节

  • ID
  • user_room_id(FK到user_room表)
  • COL1
  • COL2
  • COL3

尝试连接房间时,我希望数据库尝试为该房间提取数据。

如果数据不存在,我想查看用户表中是否存在用户名。

  • 如果用户名确实存在,我想获取他们的身份。
  • 如果用户名不存在,我想将其名称添加到用户表并捕获最后插入的ID

一旦拥有了他们的id,我想在user_room表中为该用户添加一条记录,然后根据user_room表中新插入的id为记录添加几条记录。

我似乎陷入了纠结的网络,进入了这么多层。

这就是我的代码目前的样子:

socket.on('enter room', function(data, callback){

    var sql = "select col1, col2, col3 from room JOIN user_room on room.id = user_room.room_id JOIN user on user_room.user_id = user.id JOIN details on user_room.id = details.user_room_id where username = ?";
    db_connection.query(sql, [socket.nickname], function (err, result) {

        if (err){
            console.log("ENTER ROOM DB ERROR: " + err);
            return;
        }

        if (!result.length){
            var sql = "select id from user where name = ?";

            db_connection.query(sql, [socket.nickname], function (err, result){
                if (err){
                    console.log("ENTER ROOM, SELECT ID DB ERROR: " + err);
                    return;
                }

                if (!result.length){
                    var sql = "insert into user (name) values (?)";

                    db_connection.query(sql, [socket.nickname], function(err, result){
                        if (err){
                            console.log("ENTER ROOM, INSERT ID DB ERROR: " + err);
                            return;
                        }

                        id = result.insertId;

                    });
                }
                else {
                    id = result[0].id;
                }

            });

            //We need to pull things back into one branch again here    
            //Using the user id and room id I will insert a record into the user_room table
            //Then using the newly inserted id in the user_room table, I need to add records to a details table


        }
    });

     //Send col1, col2, and col3 data back to user
     //This section here also needs to be pulled back into one branch again
     io.sockets.emit('details', result);
});

它主要起作用,但是因为我以两种不同的方式分支以获取用户ID(如果它已经存在,则为一个,如果我需要插入它,则为一个),我不知道如何将它再次拉回到一个分支。

我可以做些什么来将我的代码重新拉回到一个分支中,以便我可以再次使用该ID?或者,是否有更好的方法来完全解决这个问题?

一个附带问题:我可以安全地删除我的打开函数中的“回调”,还是应该在我的代码中使用它?我觉得发射就像是对客户端的回调,所以我不需要在这里进行“回调”。

1 个答案:

答案 0 :(得分:0)

我采用了不同的方法在userId上获取upsert。我使用promise立即发送房间数据(如果有的话)。

socket.on('enter room', function (data, callback) {
  let nickName = '';
  let roomId = '';

  return bookingDetails(nickName).then((details) => {
    if (details.length !== 0) {
      return Promise.resolve(details);
    } else {
      return createRoom(nickName, roomId);
    }
  }).then((details) => {
    io.sockets.emit('details', details);
  });
});

function createRoom(nickName, roomId) {
  return getUserDetails(nickName).then((userId) => {
    return insertUserRoom(userId, roomId); //your function
  }).then((userRoomDetails) => {
    return insertDetails(userRoomDetails); //your function
  });
}

function bookingDetails(nickName) {
  let sql = "select col1, col2, col3 from room " +
    "JOIN user_room on room.id = user_room.room_id " +
    "JOIN user on user_room.user_id = user.id " +
    "JOIN details on user_room.id = details.user_room_id where username = ?";
  return new Promise((resolve, reject) => {
    db_connection.query(sql, [nickName], function (err, details) {
      if (err) {
        return reject("ENTER ROOM DB ERROR: ");
      }
      return resolve(details);
    });
  });
}

function getUserDetails(nickName) {
  return new Promise((resolve, reject) => {
    let sql = "select id from user where name = ?";
    db_connection.query(sql, [nickName], function (err, userDetail) {
      if (err) {
        return reject(err);
      }
      if (userDetail === null) { //insert
        return createUser(nickName);
      }
      return userDetail;
    }).then((userDetail) => {
      return resolve(userDetail.id);
    });
  });
}

function createUser(nickName) {
  return new Promise((resolve, reject) => {
    let sql = "insert into user (name) values (?)";
    db_connection.query(sql, [nickName], function (err, userDetail) {
      if (err) {
        return reject(err);
      }
      return resolve(userDetail);
    });
  });
}