Javascript 解决所有问题时执行承诺(作为DB事务)
我有两个承诺需要充当事务,如果其中一个失败,应该发生“回滚” 例如:当我创建一个用户时,我想发送一封确认电子邮件,但是如果发送电子邮件时出现错误,会发生什么情况,该用户将被创建,但永远不会得到确认Javascript 解决所有问题时执行承诺(作为DB事务),javascript,typescript,es6-promise,Javascript,Typescript,Es6 Promise,我有两个承诺需要充当事务,如果其中一个失败,应该发生“回滚” 例如:当我创建一个用户时,我想发送一封确认电子邮件,但是如果发送电子邮件时出现错误,会发生什么情况,该用户将被创建,但永远不会得到确认 await saveUser(user) await sendEmail(user) await sendEmail(user) await saveUser(user) 如果我切换顺序,当创建用户时出现问题时会发生什么?它将得到确认 await saveUser(user) await send
await saveUser(user)
await sendEmail(user)
await sendEmail(user)
await saveUser(user)
如果我切换顺序,当创建用户时出现问题时会发生什么?它将得到确认
await saveUser(user)
await sendEmail(user)
await sendEmail(user)
await saveUser(user)
我以为一个承诺。所有的都会成功,但事实并非如此
await Promise.all([saveUser(user), sendEmail(user)]);
有没有办法在Javascript上以事务的形式执行承诺?承诺应在且仅在两者都解决时执行。JavaScript中没有像某些数据库中那样的内置“事务机制”。您无法及时返回以撤消已执行的操作。如果希望在sendmail
失败时逆转saveUser
的效果,则需要创建另一个函数,例如unsaveUser
,并在sendmail
失败时调用它
这可以通过以下方式完成:
使用承诺:
saveUser(user)
.then(() => sendEmail(user))
.catch(err => {
if (err.message === "Email Error") { // Check the exception to determine if the email failed
unsaveUser(user);
}
});
// This will only send the email if 'saveUser' was successful, and call 'unsaveUser' if email fails
使用Async/Await也有同样的问题:
try {
await saveUser(user);
sendEmail(user);
} catch(err) {
if (err.message === "Email Error") { // Check the exception to determine if the email failed
unsaveUser(user);
}
}
要使此示例起作用,在异步sendmail
函数中,必须抛出新错误(“电子邮件错误”)代码>在检测到错误时。如果您使用的是resolve/reject,它将是reject(新错误(“电子邮件错误”)代码>
我希望这对您来说很清楚,并帮助您解决问题。在我看来,第一步是:创建用户,然后按顺序发送电子邮件。只需将这两个调用包装在try/catch中,并在catch回滚中。(如何开始/回滚事务取决于您的数据库层。)不确定这是否值得一提,但回滚用户创建有点奇怪,因为确认电子邮件失败。有人在您的网站出现临时电子邮件中断时注册了您的网站,您是否仍然需要该用户?您可以随时将电子邮件部分排队,或在恢复服务时重新创建电子邮件。谢谢,问题是,在捕获中,我会让用户知道用户已经存在,如果我删除该用户,我将删除该用户。我考虑的是按类型处理错误,而不是确定删除的位置。如果saveUser
失败,则不应插入该用户,即没有删除的理由。如果用户已经存在,则没有理由删除现有用户。承诺不提供事务机制。你的数据库有。是的,我想这是不可能的。谢谢你的帮助response@araujo那么你应该把它标记为正确答案