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

在Rails中与ActionJob连接的常见模式是使用perform()方法设置Job,该方法通过perform_nowperform_later异步调用

在Mailers的特例中,您可以直接调用deliver_nowdeliver_later因为ActionJobActionMailer很好地集成在一起。

rails文档有以下注释 –

 # 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都会立即发送电子邮件。 在这里,您可以看到deliver方法的文档。

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

除了Daniel Batalla写的内容之外,还有一个观察结果: deliver_later似乎执行了懒惰的评估,而deliver_now则没有。

我有一个ActiveRecord模型,其中包含一个未存储在数据库中的附加属性reset_token (这是来自Michael Hartl的railstutorial.org;该模型在reset_digest列中存储了一个哈希版本的令牌)。

执行deliver_now ,访问邮件程序视图中的@modelreset_token属性会产生预期的重置令牌。 但是,在执行deliver_later@model.reset_token总是nil 。 似乎deliver_later使用数据库数据更新模型,并且因为reset_token是数据库不支持的附加属性,所以此时它将nil 。 (代码文档嵌套得太深,我无法在源代码中validation这一点。)

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