首页 > 解决方案 > 为什么即使我已经发送了响应,我的“then”承诺链接仍然执行?

问题描述

我有一个类似设置注册过程的代码。这是在我的节点应用程序的控制器中,这是完整的代码

const bcrypt = require("bcrypt")

const User = require("../models/user") // mongoose model
const ResponseData = require("../models/structureResponse")

exports.signUp= (req,res,next) => {

    const email = req.body.email
    const plainPassword = req.body.password
    const saltRounds = 12

    User.findOne({email: email})
    .then((userData) => {

        if (userData) {
            const response = new ResponseData(1,"user already exist",{})
            res.status(409).json(response)
        } else {
            return bcrypt.hash(plainPassword, saltRounds)
        }

    })
    .then((hashedPassword) => {

        const user = new User({
            email: email,
            password: hashedPassword
        })

        return user.save()
    })
    .then((user) => {

        const response = new ResponseData(1,"Successfully create a user",user)
        res.status(409).json(response)
    })
    .catch((err) => {
        const error = new Error(err);
        error.httpStatusCode = 500;
        return next(error);
    })



}

第一步是检查用户是否已经存在,使用他们的电子邮件检查User.findOne,如果用户存在,则执行以下代码:

       if (userData) {
            const response = new ResponseData(1,"user already exist",{})
            res.status(409).json(response)
        }

当我发送这样的响应,并告诉客户端用户已经存在时,下一个“then”也会被执行。我的意思是这部分:

.then((hashedPassword) => {

        const user = new User({
            email: email,
            password: hashedPassword
        })

        return user.save()
    })

我希望如果我已经发送了告诉“用户已经存在”的响应,那么它下面的 'then' 将不再执行。怎么做 ?还是我写错了承诺链?老实说,我是 node js 的新手

标签: javascriptnode.jsexpress

解决方案


.thencallbacks 返回的值将填充到下一个.then回调参数,无论您是否返回任何内容。

除了会跳转到块的内部回调之外,没有其他方法可以打破.then链。throw.thencatch

你将不得不打破你的功能而不是链接.then

我个人会async/await这样使用

exports.signUp = async (req, res, next) => {
  try {
    const email = req.body.email
    const plainPassword = req.body.password
    const saltRounds = 12

    const userExist = await User.findOne({ email })

    if (userExist) {
      const response = new ResponseData(1,"user already exist",{})
      res.status(409).json(response)
      // Now we are not inside a promise callback so we can
      // stop the execution of signUp by just returning from the function
      return
    }

    const hashedPass = await bcrypt.hash(plainPassword, saltRounds)

    const user = await new User({
      email: email,
      password: hashedPassword
    }).save()

    const response = new ResponseData(1,"Successfully create a user",user)
    res.status(409).json(response) 
  } catch (err) {
    const error = new Error(err)
    error.httpStatusCode = 500
    next(error)
  }
}

与承诺的等价物

exports.signUp = (req, res, next) => {
  const email = req.body.email
  const plainPassword = req.body.password
  const saltRounds = 12

  User.findOne({ email })
    .then((userData) => {
      if (userData) {
        const response = new ResponseData(1,"user already exist",{})
        res.status(409).json(response)
        // here we return but we dont have another .then function
        // so the rest of the code wont execute if userData is true
        return
      }

      const hashedPassword = bcrypt.hash(plainPassword, saltRounds)
      const user = new User({
        email: email,
        password: hashedPassword
      }).save()
        .then((user) => {
          const response = new ResponseData(1,"Successfully create a user",user)
          res.status(409).json(response)
        })
    }).catch((err) => {
      const error = new Error(err)
      error.httpStatusCode = 500
      next(error)
    })
}

推荐阅读