希望你们都做得很好!当我想部署这个api时,我遇到了一些困难。我不断收到这样的信息:";未处理的PromiseRejection警告:未处理的promise拒绝。这个错误要么是由于在没有catch块的异步函数内部抛出,要么是由于拒绝了没有用.catch((处理的promise;我的猜测是我发送了两次响应,但我无法确定在哪里。有人知道会发生什么吗?
router.post('/add', async (req, res) => {
const friend = await User.findOne({username:req.body.friend})
const user = await User.findById(req.body.id)
if(friend && friend != req.headers.username) {
user.friends.find((x) => {
switch(friend.username){
case user.username:{
res.status(401).json({
status: "Failed",
message: "We are sorry but you cant add yourself as friend",
data:null
})
}
case x.friend_username: {
res.status(401).json({
status: "Error",
message: `Sorry, your friend has been already added`,
data: []
})
}
default: {
User.findByIdAndUpdate(req.body.id, {
$addToSet:{
friends: {
friend_id: friend.id,
friend_username: friend.username
}
}
}, {
upsert: true,
safe: true
})
.then(result => {
res.status(200).json({
status: "Success",
message: `Friend has been added correctly! `,
data: result
})
})
.catch((err)=>{
res.status(500).json({
status: "Failed",
message: "Database Error",
data: err
})
})
}
}
})
} else {
res.status(404).json({
status: "Failed",
message: "We are sorry but the username was not found",
data:null
})
console.log(`There has been an failed attempt of adding a new user. nUser: ${req.headers.username} `)
}
})
`
Try-catch块可能有助于调试。它必须与async/await一起使用才能捕获未处理的承诺。我假设问题出在User.findOne((或User.findById((中。以太他们工作不正确,以太你在请求中传递数据不正确。
router.post('/add', async(req,res)=>{
try {
const friend = await User.findOne({username:req.body.friend})
const user = await User.findById(req.body.id)
if(friend&&friend!=req.headers.username){
user.friends.find((x)=>{
switch(friend.username){
case user.username:{
res.status(401).json({
status: "Failed",
message: "We are sorry but you cant add yourself as friend",
data:null
})
}
case x.friend_username:{
res.status(401).json({
status: "Error",
message: `Sorry, your friend has been already added`,
data: []
})
}
default:{
User.findByIdAndUpdate(req.body.id,{
$addToSet:{friends:{
friend_id:friend.id,
friend_username:friend.username
}}
},{upsert:true,safe:true})
.then(result=>{
res.status(200).json({
status: "Success",
message: `Friend has been added correctly! `,
data: result
})
})
.catch((err)=>{
res.status(500).json({
status: "Failed",
message: "Database Error",
data: err
})
})
}
} }
)}
else{
res.status(404).json({
status: "Failed",
message: "We are sorry but the username was not found",
data:null
})
console.log(`There has been an failed attempt of adding a new user. nUser: ${req.headers.username} `)
}
} catch(err) {
console.log(err);
}
})
find((和switch不间断的组合可能是原因,而且肯定会扰乱逻辑。
代码中还有一些其他可以改进的地方。以下是对评论中描述的更改的编辑。。。
router.post('/add',async(req,res)=>{
// surround the async calls with try/catch
try {
const friend = await User.findOne({ username:req.body.friend });
const user = await User.findById(req.body.id);
// detect and throw app-level errors. do the express response in the catch
// get the most basic out of the way first. we need a user and a friend for the rest of the route to work
if (!user || !friend) {
throw {
status: 404,
json: {
status: "Failed",
message: "user id or friend name not found",
data: null
}
}
}
// user adding themself as a friend doesn't need a loop to check
if (friend.username === user.username) {
throw {
status: 401,
json: {
status: "Failed",
message: "We are sorry but you cant add yourself as friend",
data:null
}
}
}
// the loop that's needed here is hidden in includes()
if (user.friends.includes(friend.username)) {
throw {
status: 401,
json: {
status: "Error",
message: `Sorry, your friend has been already added`,
data:null
}
}
}
// now, all of the errors have been detected and thrown
// do the upsert with another await and send good status
const addToSet = {
$addToSet:{friends:{
friend_id:friend.id,
friend_username:friend.username
}}
};
// note we await here (not then) since that's the style chosen above
const result = await User.findByIdAndUpdate(req.body.id, addToSet,{ upsert:true, safe:true });
res.status(200).json({
status: "Success",
message: `Friend has been added correctly! `,
data: result
});
} catch (error) {
console.log(error);
res.status(error.status).json(error.json);
}
}