提交事务后如何return查询数据(使用knex.js)?
How to I return query data after committing a transaction (using knex.js)?
我正在尝试注册用户。过程如下——我先为用户生成哈希,然后生成令牌。假设这两个步骤成功,然后我将用户添加到数据库中。
此步骤涉及将用户添加到 2 tables - 一个仅包含哈希的 user_credentials table,并使用此操作后返回的 ID 添加其他用户详细信息和令牌给用户 table.
我能够成功添加用户 - 但是,当我在将用户添加到两个 table 后尝试访问 knex 返回的用户数据时,我总是得到 Data: undefined
。
不确定从 createUser() 发回行数据并使其在下一个 then 块(控制台记录的位置)中可用的正确方法是什么。
const handleRegister = (req, res, db, bcrypt, saltRounds) => {
// Get the details from the body
let user = req.body;
// Hash the plain text password using bcrypt
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
// set user's hash to encrypted pw
user.hash = hash;
})
// Create token to be sent back to the client to create a session
.then(() => createToken())
// Set user's token to created token
.then((token)=> {
user.token = token;
})
// Save hashed password to db for the user and save user data to db with created token
.then(() => createUser(user, db))
// Return info of created user
.then((data) => {
delete user.hash;
console.log("User:", user);
console.log("Data:", data);
res.status(201).json(user);
})
.catch((err) => {
console.log("This was the error:", err);
res.status(400).json("Something went wrong");
});
}
// creating a user in the database
const createUser = (user, db) => {
return db.transaction((trx) => {
trx.insert({
hash: user.hash
})
.into('user_credentials')
.returning('id')
.then((userId) => {
return trx('users')
.returning('*')
.insert({
user_id: userId[0],
email: user.email,
name: user.name,
token: user.token,
created_at: new Date()
});
})
.then((data)=> {
return trx.commit()
.then(() => data);
})
.catch((err) => {
trx.rollback();
throw err;
})
})
}
我认为问题出在你真正坚持的 user
对象上。
// Get the details from the body
let user = req.body;
// Hash the plain text password using bcrypt
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
// set user's hash to encrypted pw
user.hash = hash;
})
// Create token to be sent back to the client to create a session
.then(() => createToken())
// Set user's token to created token
.then((token) => {
user.token = token;
})
// Save hashed password to db for the user and save user data to db with created token
// DOES THIS USER REALLY HAVE THE token AND hash?
.then(() => createUser(user, db))
您有一个从 req.body
创建的 user
实例,并使用哈希和令牌更新它。问题是您没有在创建令牌后 return 更新的 user
实例(带有哈希)。由于 promises 是异步的,您无法确保您确实在处理更新后的实例。因此,您可能会处理过时的实例。
我想你可以开始操作一个新的用户实例。
let user = req.body;
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
user.hash = hash;
return user
})
.then((user) => {
user.token = createToken()
return user
})
.then((user) => createUser(user, db)) // Create User with a really updated instance of user
我想你可以开始了
OK,睡了一觉,似乎找到了解决办法。
db.transaction 似乎创建了一个未决承诺,该承诺要么被 trx.commit 解决,要么被 trx.rollback 拒绝。因此,需要将包含提交和回滚的整个事务视为一个块,然后 then
块在成功插入后返回数据行。请参阅下面的代码。
如果有人想了解更多,请参考 - https://github.com/tgriesser/knex/issues/1346
http://knexjs.org/#Transactions
const createUser = (user, db) => {
return db.transaction((trx) => {
trx.insert({
hash: user.hash
})
.into('user_credentials')
.returning('id')
.then((userId) => {
return trx('users')
.returning('*')
.insert({
user_id: userId[0],
email: user.email,
name: user.name,
token: user.token,
created_at: new Date()
});
})
.then(trx.commit)
.catch((err) => {
trx.rollback();
throw err;
})
})
//Return the data here instead of along with trx.commit
.then((data) => {
return data;
})
.catch((err) => {
console.log(err);
});
}
我正在尝试注册用户。过程如下——我先为用户生成哈希,然后生成令牌。假设这两个步骤成功,然后我将用户添加到数据库中。
此步骤涉及将用户添加到 2 tables - 一个仅包含哈希的 user_credentials table,并使用此操作后返回的 ID 添加其他用户详细信息和令牌给用户 table.
我能够成功添加用户 - 但是,当我在将用户添加到两个 table 后尝试访问 knex 返回的用户数据时,我总是得到 Data: undefined
。
不确定从 createUser() 发回行数据并使其在下一个 then 块(控制台记录的位置)中可用的正确方法是什么。
const handleRegister = (req, res, db, bcrypt, saltRounds) => {
// Get the details from the body
let user = req.body;
// Hash the plain text password using bcrypt
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
// set user's hash to encrypted pw
user.hash = hash;
})
// Create token to be sent back to the client to create a session
.then(() => createToken())
// Set user's token to created token
.then((token)=> {
user.token = token;
})
// Save hashed password to db for the user and save user data to db with created token
.then(() => createUser(user, db))
// Return info of created user
.then((data) => {
delete user.hash;
console.log("User:", user);
console.log("Data:", data);
res.status(201).json(user);
})
.catch((err) => {
console.log("This was the error:", err);
res.status(400).json("Something went wrong");
});
}
// creating a user in the database
const createUser = (user, db) => {
return db.transaction((trx) => {
trx.insert({
hash: user.hash
})
.into('user_credentials')
.returning('id')
.then((userId) => {
return trx('users')
.returning('*')
.insert({
user_id: userId[0],
email: user.email,
name: user.name,
token: user.token,
created_at: new Date()
});
})
.then((data)=> {
return trx.commit()
.then(() => data);
})
.catch((err) => {
trx.rollback();
throw err;
})
})
}
我认为问题出在你真正坚持的 user
对象上。
// Get the details from the body
let user = req.body;
// Hash the plain text password using bcrypt
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
// set user's hash to encrypted pw
user.hash = hash;
})
// Create token to be sent back to the client to create a session
.then(() => createToken())
// Set user's token to created token
.then((token) => {
user.token = token;
})
// Save hashed password to db for the user and save user data to db with created token
// DOES THIS USER REALLY HAVE THE token AND hash?
.then(() => createUser(user, db))
您有一个从 req.body
创建的 user
实例,并使用哈希和令牌更新它。问题是您没有在创建令牌后 return 更新的 user
实例(带有哈希)。由于 promises 是异步的,您无法确保您确实在处理更新后的实例。因此,您可能会处理过时的实例。
我想你可以开始操作一个新的用户实例。
let user = req.body;
bcrypt.hash(user.password, saltRounds)
.then((hash) => {
delete user.password;
user.hash = hash;
return user
})
.then((user) => {
user.token = createToken()
return user
})
.then((user) => createUser(user, db)) // Create User with a really updated instance of user
我想你可以开始了
OK,睡了一觉,似乎找到了解决办法。
db.transaction 似乎创建了一个未决承诺,该承诺要么被 trx.commit 解决,要么被 trx.rollback 拒绝。因此,需要将包含提交和回滚的整个事务视为一个块,然后 then
块在成功插入后返回数据行。请参阅下面的代码。
如果有人想了解更多,请参考 - https://github.com/tgriesser/knex/issues/1346 http://knexjs.org/#Transactions
const createUser = (user, db) => {
return db.transaction((trx) => {
trx.insert({
hash: user.hash
})
.into('user_credentials')
.returning('id')
.then((userId) => {
return trx('users')
.returning('*')
.insert({
user_id: userId[0],
email: user.email,
name: user.name,
token: user.token,
created_at: new Date()
});
})
.then(trx.commit)
.catch((err) => {
trx.rollback();
throw err;
})
})
//Return the data here instead of along with trx.commit
.then((data) => {
return data;
})
.catch((err) => {
console.log(err);
});
}