即使在 return 之后函数仍继续执行
Function continues execution even after return
我的问题很简单,当我运行下面的代码和检查数据库时,我发现用户被成功删除,这意味着User.findOneAndDelete
被执行,承诺被履行并且我期望在响应中看到 { success: 'user_deleted' }
;但是,我得到 { error: 'user_not_found' }
这应该只有在用户不存在时才会发生,但这里不是这种情况,因为 IF 块内的代码是根据我在数据库中的观察执行的。
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;
});
现在为了解决这个问题,我尝试添加一个 else
语句,而不是我之前使用的隐式方式,它按预期工作,我得到了 `{ success: 'user_deleted' }响应。
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;
};
});
我的问题是:为什么会发生这种行为?为什么执行已经跳到函数的底部了?还有为什么走到函数底部响应的时候,删除是怎么发生的,在DB中删除了User,我这里比较迷惑。
编辑:当我将父函数转换为 async
函数并在数据库操作中使用 await 时,它的行为也符合预期。
您的代码的问题是最后一个 res.json({ error: 'user_not_found' })
调用。
如果仔细观察,由于内部查询是异步的,因此甚至在触发内部删除查询之前就触发了这一行。
所以在第一种情况下,无论用户是否存在,函数总是returns响应。
将 else 放入您的代码块基本上会执行 either this or that
逻辑,因此如果用户存在,res.json({ error: 'user_not_found' })
将永远不会被调用。
EDIT : Alternative Code Using Async-Await
在这种情况下使用 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 - 您可以为 User.exists
API 设置类似的 async-await
,前提是其父函数标记为 async
.
希望对您有所帮助。
findOneAndDelete
returns a Promise
,它不会阻止剩余代码的执行(除非如您所指出的那样,函数是 async
并且你等着吧)。此外,您不是从 if 分支 returning(then
内的 return
只会从 then
中的回调中 return ),因此其余代码在外面将以任何一种方式执行。它可能只有在你等待(没有 return
)时才有效,因为此时已经发送了响应。
我的问题很简单,当我运行下面的代码和检查数据库时,我发现用户被成功删除,这意味着User.findOneAndDelete
被执行,承诺被履行并且我期望在响应中看到 { success: 'user_deleted' }
;但是,我得到 { error: 'user_not_found' }
这应该只有在用户不存在时才会发生,但这里不是这种情况,因为 IF 块内的代码是根据我在数据库中的观察执行的。
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;
});
现在为了解决这个问题,我尝试添加一个 else
语句,而不是我之前使用的隐式方式,它按预期工作,我得到了 `{ success: 'user_deleted' }响应。
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;
};
});
我的问题是:为什么会发生这种行为?为什么执行已经跳到函数的底部了?还有为什么走到函数底部响应的时候,删除是怎么发生的,在DB中删除了User,我这里比较迷惑。
编辑:当我将父函数转换为 async
函数并在数据库操作中使用 await 时,它的行为也符合预期。
您的代码的问题是最后一个 res.json({ error: 'user_not_found' })
调用。
如果仔细观察,由于内部查询是异步的,因此甚至在触发内部删除查询之前就触发了这一行。
所以在第一种情况下,无论用户是否存在,函数总是returns响应。
将 else 放入您的代码块基本上会执行 either this or that
逻辑,因此如果用户存在,res.json({ error: 'user_not_found' })
将永远不会被调用。
EDIT : Alternative Code Using Async-Await
在这种情况下使用 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 - 您可以为 User.exists
API 设置类似的 async-await
,前提是其父函数标记为 async
.
希望对您有所帮助。
findOneAndDelete
returns a Promise
,它不会阻止剩余代码的执行(除非如您所指出的那样,函数是 async
并且你等着吧)。此外,您不是从 if 分支 returning(then
内的 return
只会从 then
中的回调中 return ),因此其余代码在外面将以任何一种方式执行。它可能只有在你等待(没有 return
)时才有效,因为此时已经发送了响应。