如何仅在findByUsername的Promise被拒绝时执行createUser函数?
实现仅当用户名不存在时创建用户的函数
首先需要修正现有findByUsername函数的逻辑——原代码中仅在数据库查询出错时才会reject,但根据你的需求,应该在查询成功但未找到用户时reject,查询到用户时resolve:
const findByUsername = (name) => { return new Promise((res, rej) => { pool.query( "SELECT * FROM users WHERE username = $1", [name], (error, results) => { if (error) { // 数据库查询出错,抛出错误 return rej(error); } if (results.rows[0]) { // 找到用户,返回用户信息 res(results.rows[0]); } else { // 未找到用户,抛出提示 rej("用户名不存在"); } } ); }); };
接下来实现createUser函数,它负责插入新用户并返回Promise:
const createUser = (username, userData) => { return new Promise((res, rej) => { // 根据你的表结构调整字段和占位符,这里示例包含username、email、password pool.query( "INSERT INTO users (username, email, password) VALUES ($1, $2, $3) RETURNING *", [username, userData.email, userData.password], (error, results) => { if (error) { return rej(error); } // 返回创建完成的用户数据 res(results.rows[0]); } ); }); };
方式一:Promise链式调用实现逻辑
利用Promise的catch方法捕获findByUsername的reject(即用户名不存在的情况),在此分支执行创建操作;若findByUsernameresolve(用户名存在),则主动抛出错误:
const createUserIfNotExists = (username, userData) => { return findByUsername(username) .then((existingUser) => { // 用户名已存在,抛出错误终止流程 return Promise.reject(new Error("用户名已存在")); }) .catch((err) => { // 区分错误类型:仅当是"用户名不存在"时执行创建 if (err === "用户名不存在") { return createUser(username, userData); } // 其他错误(如数据库查询异常、用户名已存在)直接抛出 return Promise.reject(err); }); };
方式二:async/await实现(更简洁易读)
用async/await语法替代链式调用,逻辑更直观:
const createUserIfNotExists = async (username, userData) => { try { const existingUser = await findByUsername(username); // 若执行到此处,说明用户名已存在 throw new Error("用户名已存在"); } catch (err) { if (err === "用户名不存在") { // 用户名不存在,执行创建 return await createUser(username, userData); } // 其他错误重新抛出 throw err; } };
使用示例
调用createUserIfNotExists并处理结果:
createUserIfNotExists("newuser", { email: "newuser@example.com", password: "your_hashed_password" }) .then((newUser) => { console.log("用户创建成功:", newUser); }) .catch((err) => { console.error("创建失败:", err.message || err); });
注意事项
- 始终使用参数化查询(如
$1、$2)避免SQL注入风险; - 错误处理需区分数据库异常、用户名已存在、用户名不存在三种场景,便于前端或后续逻辑处理;
createUser中的RETURNING *用于返回插入后的用户数据,可根据需求调整返回字段。
内容的提问来源于stack exchange,提问作者Blakjay116
相关产品推荐
相关产品推荐

