Action Job/Mailer 的 `deliver_now` 和 `deliver_later` 之间的区别

Difference between Action Job/Mailer's `deliver_now` and `deliver_later`

在 Rails 中与 ActiveJob 交互的常见模式是使用 perform() 方法设置一个作业,该方法通过 perform_now 或 [=17] 异步调用=]

在 Mailers 的特殊情况下,您可以直接调用 deliver_nowdeliver_later,因为 ActiveJobActionMailer 集成得很好。

rails documentation有以下评论-

# If you want to send the email now use #deliver_now
UserMailer.welcome(@user).deliver_now
 
# If you want to send the email through Active Job use #deliver_later
UserMailer.welcome(@user).deliver_later

措辞使 deliver_now 看起来 不会 使用 ActiveJob 发送邮件。这是正确的吗?如果是的话,deliver_nowdeliver_later 之间的真正区别是什么?一个不是异步的吗?

同样,perform_nowperform_later 是否也有同样的区别?

谢谢!

正如您在问题中所说,deliver_now 不使用 ActiveJob

基本上,deliver_later 是异步的。当您使用此方法时,电子邮件此时不会发送,而是被推送到作业队列中。如果作业不是 运行,则不会发送电子邮件。 deliver_now 将立即发送电子邮件,无论作业的状态如何。 Here 您可以查看 deliver 方法的文档。

根据您的第二个问题,perform_now 将立即处理该作业,而不会发送到队列。但是,perform_later 会将作业添加到队列中,一旦作业的队列空闲,就会执行该作业。 Here 您可以查看 perform 方法的文档。

除了丹尼尔·巴塔拉 (Daniel Batalla) 所写的内容之外,还有一个我的观察结果:deliver_later 似乎执行惰性求值,而 deliver_now 不执行。

我有一个带有附加属性 reset_token 的 ActiveRecord 模型,该属性未存储在数据库中(这来自 Michael Hartl 的 railstutorial.org;该模型在 reset_digest列)。

执行 deliver_now 时,访问邮件程序视图中 @modelreset_token 属性会按预期生成重置令牌。然而,当执行deliver_later时,@model.reset_token总是nil。看起来好像 deliver_later 使用数据库数据更新模型,并且因为 reset_token 是一个不受数据库支持的附加属性,所以此时它将是 nil。 (代码文档嵌套太深,我无法在源代码中验证这一点。)

Michael 在教程中使用 deliver_now。我不知道他这样做是为了避免懒惰的评估。但我花了一段时间才意识到我只需将 deliver_later 更改为 deliver_now 即可使我的测试通过。