【问题标题】:Nodejs Promise TypeError: Cannot read property 'then' of undefinedNodejs Promise TypeError:无法读取未定义的属性'then'
【发布时间】:2018-06-02 20:50:35
【问题描述】:

当我尝试在我的route 中访问controller 的功能时出错。我用猫鼬,快递。

错误:

TypeError:无法读取未定义的属性“then” 在 /private/var/www/html/sms/server/routes/user.routes.js:70:9 在 Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) 在下一个(/private/var/www/html/sms/node_modules/express/lib/router/route.js:137:13) 在 Route.dispatch (/private/var/www/html/sms/node_modules/express/lib/router/route.js:112:3) 在 Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) 在/private/var/www/html/sms/node_modules/express/lib/router/index.js:281:22 在 Function.process_params (/private/var/www/html/sms/node_modules/express/lib/router/index.js:335:12) 在下一个(/private/var/www/html/sms/node_modules/express/lib/router/index.js:275:10) 在 Function.handle (/private/var/www/html/sms/node_modules/express/lib/router/index.js:174:3) 在路由器(/private/var/www/html/sms/node_modules/express/lib/router/index.js:47:12) 在 Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) 在 trim_prefix (/private/var/www/html/sms/node_modules/express/lib/router/index.js:317:13) 在/private/var/www/html/sms/node_modules/express/lib/router/index.js:284:7 在 Function.process_params (/private/var/www/html/sms/node_modules/express/lib/router/index.js:335:12) 在下一个(/private/var/www/html/sms/node_modules/express/lib/router/index.js:275:10) 在 /private/var/www/html/sms/server.js:65:3 POST /api/user/create 500 27.274 ms - 16 (node:11300) UnhandledPromiseRejectionWarning: 未处理的承诺拒绝(拒绝 id:1):错误:此电子邮件是 已经存在。请输入另一个电子邮件。 (节点:11300)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 具有非零退出代码的 Node.js 进程。

这是我的代码:-

user.cont.js

function create(data) {
  User.findOne({ email: data.email })
    .exec((err, doc) => {
      if (err) {
        return new Promise((resolve, reject) => {
          return reject(err);
        })
      } else {
        if (doc) {
          return new Promise((resolve, reject) => {
            return reject(new Error('This email is already exists. Please enter another email.'));
          })
        } else {
          const user = new User(data);
          return user.save()
        }
      }

    })

}


export default { getUsers, create };

user.route.js

router.post('/create', (req, res, next) => {
        UserCtrl.create(req.body)
            .then(savedUser => res.json(savedUser)) . // here error is generated
            .catch(e => next(e));
    });

【问题讨论】:

  • 您的create 函数中缺少return

标签: node.js express mongoose promise


【解决方案1】:

您应该将整个 User.findOne() 调用包装在一个 Promise 中,如下所示:

function create(data) {
  return new Promise((resolve, reject) => {
    User.findOne({ email: data.email })
      .exec((err, doc) => {
        if (err) return reject(err)
        if (doc) return reject(new Error('This email is already exists. Please enter another email.'))
        const user = new User(data)
        user.save((err) => {
          if (err) return reject(err)
          resolve()
        })
      })
  })
}

您还需要解决承诺,否则您的 UserCtrl.then() 调用中的回调将永远不会被调用。我还添加了错误处理,以防将新的User 保存到数据库时出现问题。

【讨论】:

  • 当然,在当前版本的 Mongoose 中,.findOne 返回一个 Promise,所以你可以避免这个 Promise 构造函数反模式
【解决方案2】:

您也可以将控制器和路由代码重构为这样。

user.cont.js

function create(req, res, next){
   User.findOne({email: req.body.email})
    .then((err, user) => {

      if(user){

        const newUser = User.create(req.body,  (newUser, err) => {
          if(err) res.send(err);

          delete newUser.password;
          res.json(newUser)
        })
      }


    }).catch((err) => {
       res.send(err)
    })


}

由于User.findOne 已经返回了一个promise,您可以在上面调用.then,如果用户有密码,请确保在将其返回给客户端之前删除用户密码!

请注意,您也可以在 create 函数上调用 .then,也许您可​​以将其重构为使用 .then 进行练习 :)


user.route.js

router.post('/create', UserCtrl.create)

现在您的路线代码看起来更清晰了,并且您更好地遵循了关注点分离!

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 2018-01-15
    • 2019-08-19
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多