You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript async/await最佳实践:Express代码冗余写法疑问

关于ExpressJS+TypeScript中async/await嵌套使用的最佳实践疑问

我在ExpressJS中使用TypeScript开发密码找回功能,编写了如下精简代码,现在有个疑问:执行const results = await checkForEmailAddress(email);时,调用async函数前使用了await,而该函数内部也采用了async/await写法,想确认这种做法是否符合最佳实践,是否存在冗余。

/**
 * Verifies that an email address exists in the DB.
 * If so, sends them an email to recover their password.
 * 
 * @param {Request} req 
 * @param {Response} res 
 */
const sendPasswordRecoveryEmail = (req: Request, res: Response) => {
  const email = req.body.email

  const checkForEmailAddress = async (email: string) => {
    return await pool.query(`SELECT password FROM users WHERE email = $1`, [email]);
  };

  const updatePasswordFields = async (password: string, newPassword: string, email: string) => {
    return await pool.query(`UPDATE users SET last_password = $1, password = $2 WHERE email = $3`, [password, newPassword, email]);
  };

  const passwordRecoveryProcess = async (email: string) => {
    try {
      res.status(200).send({ status: true, message: 'Password recovery process initiated.' });

      const results = await checkForEmailAddress(email);
      if (results.rows.length === 1) {
        const existingPassword = results.rows[0].password;
        const newTempPassword = generateRandomPassword();
        await updatePasswordFields(existingPassword, newTempPassword, email);
        const body = `...`;
        emailService({email, subject: 'MySite Password Recovery', body});
      }
    } catch (error) {
      console.error('Error', error);
    }
  }

  passwordRecoveryProcess(email); // Initiate async Password Recovery Process
};

回答

这种写法符合最佳实践,不存在功能上的冗余,具体解释如下:

  • 外层调用checkForEmailAddress时使用await是必要的:因为checkForEmailAddress是async函数,返回的是一个Promise,只有用await才能等待这个Promise完成,拿到实际的数据库查询结果,否则后续判断results.rows.length会因为拿到Pending状态的Promise而报错。
  • 内部函数里的await本身是合理的:pool.query是异步操作,返回Promise,内部用await是为了等待数据库操作完成,确保函数返回的是查询结果的Promise。不过这里可以做简洁化优化:因为pool.query已经返回Promise,async函数会自动将返回值包装为Promise,所以可以去掉内部的await,直接返回pool.query的结果,效果完全一致,比如:
    const checkForEmailAddress = async (email: string) => {
      return pool.query(`SELECT password FROM users WHERE email = $1`, [email]);
    };
    
    甚至可以去掉async关键字,直接返回Promise:
    const checkForEmailAddress = (email: string) => {
      return pool.query(`SELECT password FROM users WHERE email = $1`, [email]);
    };
    
    这两种优化写法和原代码功能完全相同,但更简洁。原代码的写法虽然多了一层await包装,但不会影响功能和性能,只是略显冗余,并非错误写法。

内容的提问来源于stack exchange,提问作者RobertW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 10:39:16