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.any 不是函数
未捕获的 Promise 错误:TypeError:成员不是函数
vue控制台报 Uncaught (in promise) TypeError: