Promise或回调,哪一个更适合在NodeJS中使用?

huangapple go评论76阅读模式
英文:

Promise or Callback, which one is better to use with NodeJS?

问题

以下是翻译好的部分:

我发现编写节点函数有两种不同的方式,一种是使用promise,另一种是使用callback。第一种方式如下定义了findByEmail函数:

class Users {
  static async findByEmail(email: any): Promise<Users | undefined> {
    const user: any = await Pools.execute(
      "SELECT * FROM users WHERE email = ?",
      [email]
    )
      .then((rows) => {
        return rows[0];
      })
      .catch((err) => console.log(err));
    return user;
  }
}

router.post(
  "/api/users/signin",
  async (req: Request, res: Response, next: NextFunction) => {
    const { email, password } = req.body;
    const existingUser = await Users.findByEmail(email);
  }
);

第二种方式如下:

declare global {
  namespace Express {
    interface Response {
      user?: Users;
    }
  }
}

static async findByEmail(req: Request, res: Response) {
  const user = await Pools.execute(
    "SELECT * FROM users WHERE email = ?",
    [req.body.email]
  )
    .then((rows) => {
      res.user = rows[0];
    })
    .catch((err) => console.log(err));
};

router.post(
  "/api/users/signin",
  async (req: Request, res: Response, next: NextFunction) => {
    await Users.findByEmail(req, res);
    const existingUser = res.user;
  }
);

关于哪种方式更好的问题是否基于个人意见可能会有争议。但我提问的目的是想知道哪种方式是更好的实践,以及为什么?根据性能和其他可能的问题?

我特别想知道是否更好地使用return值编写函数,还是在then()函数中使用response对象添加返回值,例如.then(res.user = user)而不是const user = await pool.execute(SELECT ...)

英文:

I found that there are 2 different ways to write node functions using promise or callback, the first way is like following defining the findByEmail function:

class Users{
  static async findByEmail(email: any ) : Promise&lt;Users | undefined&gt;{
    const user: any = await Pools.execute(
      &quot;SELECT * FROM users WHERE email = ?&quot;,
      [email])
      .then(rows =&gt; { 
        return rows[0];
       })
      .catch(err =&gt; console.log(err) );
      return user;
  };
}

router.post(
  &quot;/api/users/signin&quot;,
  async (req: Request, res: Response , next: NextFunction) =&gt; {
     const { email, password } = req.body;
     const existingUser = await Users.findByEmail(email);
});

And the second way would be like:

declare global {
  namespace Express {
    interface Response {
      user?: Users;
    }
  }
}

  static async findByEmail(req: Request, res: Response) {
    const user = await Pools.execute(
      &quot;SELECT * FROM users WHERE email = ?&quot;,
      [req.body.email])
      .then(rows =&gt; { 
         res.user = rows[0];
       })
      .catch(err =&gt; console.log(err) );
  };




router.post(
  &quot;/api/users/signin&quot;,
  async (req: Request, res: Response , next: NextFunction) =&gt; {
    await Users.findByEmail(req, res);
    const existingUser = res.user;
});

I am not sure if this is a "opinion based" question or not? However my purpose of asking this is to know which way is a better practice and why? According to performance and other possible issues?

In particular I like to know either it is better to write functions with the return value or using response object to add the returning value to that inside the then() function, like .then(res.user = user) instead of const user = await pool.execute(SELECT ...) ?

答案1

得分: 1

这里有一种改进方法:

  1. findByEmail()改为一个实用函数,与reqres对象无关,因此可以通用使用。
  2. 正确地将所有来自findByEmail()的错误传递给调用者。
  3. 对传入的电子邮件字段执行一些验证检查,并创建单独的错误路径。
  4. 记录服务器上的所有错误。
  5. 检查数据库请求的所有错误条件。
  6. 不混合使用.then()await

以下是代码:

// 如果未找到电子邮件则解析为null
// 如果存在数据库错误则拒绝
static async findByEmail(email) {
    const rows = await Pools.execute("SELECT * FROM users WHERE email = ?", [email]);
    if (!rows || !rows.length || !rows[0]) {
        return null;
    }
    return rows[0];
};

router.post("/api/users/signin", async (req: Request, res: Response, next: NextFunction) => {
    try {
        // 验证传入参数
        if (!req.body.email) {
            let errMsg = "在传入的登录请求中没有电子邮件值";
            console.log(errMsg);
            res.status(400).send(errMsg);
            return;
        }
        let user = await Users.findByEmail(req.body.email);
        if (!user) {
            // 如果用户尝试使用不存在的电子邮件登录,执行你想要的操作
            // 可能返回类似404状态的内容
        } else {
            // 在登录后对用户对象执行所需操作
        }
    } catch(e) {
        // 这里发生了某种服务器错误,可能是数据库错误,不是客户端的错误
        console.log(e);
        res.sendStatus(500);
    }
});
英文:

Here's a way to impalement that makes the following improvements:

  1. Makes findByEmail() into a utility function that is independent of the req and res objects and thus can be used generally.
  2. Properly propagates all errors from findByEmail() back to the caller.
  3. Implements some validation checks on incoming email field and makes separate error path for that.
  4. Log all errors on the server
  5. Check for all error conditions from the database request
  6. Not mixing .then() and await.

Here's the code:

// resolves to null if email not found
// rejects if there&#39;s a database error
static async findByEmail(email) {
    const rows = await Pools.execute(&quot;SELECT * FROM users WHERE email = ?&quot;, [email]);
    if (!rows || !rows.length || !rows[0]) {
        return null;
    }
    return rows[0];
};

router.post(&quot;/api/users/signin&quot;, async (req: Request, res: Response, next: NextFunction) =&gt; {
    try {
        // validate incoming parameters
        if (!req.body.email) {
            let errMsg = &quot;No email value present in incoming signin request&quot;;
            console.log(errMsg);
            res.status(400).send(errMsg);
            return;
        }
        let user = await Users.findByEmail(req.body.email);
        if (!user) {
            // do whatever you would do if user tries to signin with non-existent email
            // presumably return something like a 404 status
        } else {
            // do whatever you wanted to do here with the user object after login
        }
    } catch(e) {
        // some sort of server error here, probably a database error, not the client&#39;s fault
        console.log(e);
        res.sendStatus(500);
    }
});

huangapple
  • 本文由 发表于 2023年1月10日 14:01:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75066037.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定