为什么即使我发送了响应,我的“ then”承诺链仍然保持执行状态?

时间:2019-08-26 06:12:45

标签: javascript node.js express

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

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的新手

2 个答案:

答案 0 :(得分:1)

您也必须return第二then()。因为正确的知道您不会返回您的回复。

.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)
       return res.status(409).json(response)
    })

答案 1 :(得分:1)

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

除了.then回调中的throw以外,没有一种方法可以中断.then链,这会跳到catch块。

您将不得不中断功能而不是链接.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)
    })
}