express - 无法在承诺内调用 res.send()
问题描述
我正在使用回调重构我的代码。当然,第一个解决方案中的所有内容都按预期工作:
const newUser = new User({
email,
password,
})
User.exists({ email }, (err, userExists) => {
if (err) {
return next(err)
}
if (userExists) {
return res.status(400).send("A user with that email already exists")
}
newUser.save()
.then(result => console.log('new user successfully registered!:', result))
.catch(err => {
console.error('Cannot save user: ', err)
})
var profile = _.pick(req.body, 'email', 'password', 'extra')
res.status(201).send({
id_token: createIdToken(profile),
access_token: createAccessToken()
})
})
这是重构之后:
User.exists({ email })
.then(userExists => {
if (userExists) {
res.status(400).send("A user with that email already exists")
}
})
.then(() => {
const newUser = new User({
email,
password,
})
return newUser
})
.then(newUser => {
console.log('newUser: ', newUser);
return newUser.save()
})
.then(result => console.log('new user successfully registered!:', result))
.catch(err => {
console.error('Cannot save user: ', err)
return next(err)
})
但是,这不起作用。我已经隔离了承诺链中发生错误的位置,并且在我尝试将响应发送回客户端时发生res.send
我得到的错误是:C
无法保存用户:错误:发送后无法设置标题。在 validateHeader (_http_outgoing.js:491:11) 在 ServerResponse.setHeader (_http_outgoing.js:498:3) 在 ServerResponse.header (/home/kyle/programming/projects/never-forget/server/node_modules/express/lib/ response.js:771:10) 在 ServerResponse.send (/home/kyle/programming/projects/never-forget/server/node_modules/express/lib/response.js:170:12) 在 /home/kyle/programming/ projects/never-forget/server/src/controllers/users.js:47:22 at process._tickDomainCallback (internal/process/next_tick.js:229:
cannot set headers after they are sent
是不言自明的,但是我看不到在发送请求后我尝试在程序中的哪个位置发送标头。看到res.send
请求结束,我看不出还应该包括什么。
解决方案
我能想到的问题是:
在回调实现中,当userExists
为真时,您正在调用return res.status(400).send("A user with that email already exists")
结束回调并且res.status(201).send({...})
不会被调用。
但是,在 promise 实现中,当userExists
为真时,它们都会被调用。
所以,你可以在 之后抛出一个错误return res.status(400).send("A user with that email already exists")
,并在 catch 块中捕获它,它将结束主回调,即通过return next(err);
推荐阅读
- javascript - 从 Javascript 文件生成 Typescript 定义
- angular - 动态添加数据到 MatTableDataSource Material Angular
- javascript - 从多个工作表中复制行并删除
- javascript - 用户刷新页面时如何使Javascript文件不重置
- c# - 如何在 XPath .net 应用程序中按索引选择元素
- python - 将存储为 Azure Blob 的 CSV 直接加载到 Pandas 数据帧中,而无需先保存到磁盘
- angular - 如何使用带条件的 mat 表扩展行
- c# - 标签未显示随机模拟的输出
- spring-boot - 如何使用默认类从 JSON 登录尝试中读取用户凭据?
- android - Android Bluedroid BLE:某些手机没有收到来自 GATT 服务器的通知?