我的问题很简单,当我运行以下代码并检查数据库时,我发现用户已成功删除,这意味着User.findOneAndDelete
已执行,promise已兑现,我希望看到{{1 }};但是,我得到的{ success: 'user_deleted' }
仅在不存在用户的情况下才发生,在这里不是这种情况,因为IF块中的代码是根据我在数据库中的观察执行的。
{ error: 'user_not_found' }
现在要解决此问题,我尝试添加一个User.exists({ username}).then(exists => {
if (exists) {
User.findOneAndDelete({ username }).then(() => {
res.json({ success: 'user_deleted' });
return;
}
).catch(err => {
res.json({ error: 'user_delete_fail' });
return;
})
};
res.json({ error: 'user_not_found' })
return;
});
语句,而不是之前执行的隐式方式,它按预期方式工作,并且在响应中得到了“ {success:'user_deleted'}”。 / p>
else
我的问题是:为什么会发生这种现象?为什么执行已经跳到函数底部?以及为什么当它到达函数底部并做出响应时,如何发生删除操作以及如何在数据库中删除用户,我在这里很困惑。
编辑:当我将父函数转换为User.exists({ username}).then(exists => {
if (exists) {
User.findOneAndDelete({ username }).then(() => {
res.json({ success: 'user_deleted' });
return;
}
).catch(err => {
res.json({ error: 'user_delete_fail' });
return;
})
} else {
res.json({ error: 'user_not_found' })
return;
};
});
函数并在数据库操作上使用await时,它的行为也符合预期。
答案 0 :(得分:2)
您的代码存在问题,是最后一次res.json({ error: 'user_not_found' })
调用。
如果仔细看,由于内部查询是异步的,因此甚至在内部删除查询被触发之前,该行也会被触发。
因此,在第一种情况下,无论用户是否存在,该函数总是返回响应。
在代码块中放入其他内容基本上会执行either this or that
逻辑,因此如果用户存在,res.json({ error: 'user_not_found' })
将永远不会被调用。
编辑:使用异步等待的备用代码
在这种情况下使用async-await
会更有意义,因为它可以简化代码,请检查下面的代码,这些代码应该完全满足您的需要而无需使用else
。
它还避免了嵌套,从而简化了代码
User.exists({ username }).then(async exists => {
try {
if (exists) {
// this await will remove the need of inner promise chaining
await User.findOneAndDelete({ username });
res.json({ success: 'user_deleted' });
}
// in this case, this will no longer be performed before delete query
res.json({ error: 'user_not_found' });
} catch (error) {
res.json({ error: 'user_delete_fail' });
}
});
PS-对于async-await
API,您可以有类似的User.exists
,只要其父功能标记为async
。
我希望这会有所帮助。
答案 1 :(得分:1)
findOneAndDelete
返回一个Promise
,它将不会阻止其余代码的执行(如您所指出的,函数为async
并且等待它时除外)。此外,您不会从if分支返回(return
内部的then
仅从then
中的回调返回),因此外部的其余代码将以任何一种方式执行。它可能仅在您等待时(没有return
)才有效,因为响应已在该点发送。