再次将单独的asynchronous分支重新导回到一个分支中

我正在使用express和mysql库的节点js应用程序。

我有一个MySQL用户表与以下列:

  • 自动递增主要ID
  • 用户名varchar唯一

没有密码等

其他表格包括:

房间

  • ID
  • ROOM_NAME

user_room

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

细节

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

在尝试连接到一个房间时,我希望数据库尝试为该房间拉取他们的数据。

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

  • 如果用户名存在,我想获得他们的ID。
  • 如果用户名不存在,我想将他们的名字添加到用户表中,并捕获最后插入的ID

一旦拥有了自己的ID,我想为该用户的user_room表添加一条logging,然后根据user_room表中新插入的ID为细节表添加几条logging。

我似乎陷入了一个混乱的networking进入这么多层。

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

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? 或者,有没有更好的办法来处理这个问题呢?

一个侧面的问题:我可以安全地删除我的打开函数中的“callback”,或者我应该在我的代码中的某个地方使用? 我觉得这个发射像是一个callback客户端,所以我不需要在这里“callback”。

我采取了不同的方法来获取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); }); }); }