Nodejs Promise TypeError:无法读取未定义的属性'then'

Posted

技术标签:

【中文标题】Nodejs Promise TypeError:无法读取未定义的属性\'then\'【英文标题】: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 【参考方案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)

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

【讨论】:

以上是关于Nodejs Promise TypeError:无法读取未定义的属性'then'的主要内容,如果未能解决你的问题,请参考以下文章

TypeError: #<Promise> 不可迭代

出现错误 TypeError: Promise.any 不是函数

未捕获的 Promise 错误:TypeError:成员不是函数

vue控制台报 Uncaught (in promise) TypeError:

redux-promise:未捕获的 TypeError:中间件不是函数

正确使用 Promise.resolve().then() 错误:未捕获(在承诺中):TypeError:无法读取属性