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那么你应该把它标记为正确答案