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

use*_*003 18 jobs ruby-on-rails rails-activejob

ActionJob在Rails中连接的常见模式是使用一个perform()方法设置一个Job,该方法通过perform_now或者异步调用perform_later

在邮件程序的特殊情况下,可以直接打电话deliver_nowdeliver_later因为ActionJob是很好的集成ActionMailer.

轨道文档有以下评论-

# 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
Run Code Online (Sandbox Code Playgroud)

措辞使得它看起来像deliver_now不会使用ActiveJob发送邮件.那是正确的,如果有啥之间真正的差异deliver_nowdeliver_later?一个不是异步的吗?

同样,同样的差异适用于perform_nowperform_later

谢谢!

Dan*_*lla 21

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

基本上deliver_later是异步的.使用此方法时,此时不会发送电子邮件,而是将其推送到作业的队列中.如果作业未运行,则不会发送电子邮件.deliver_now无论工作状态如何,此时都会发送电子邮件.在这里,您可以看到deliver方法的文档.

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

  • @gates`admin_later`在服务器端进行管理,因此浏览器连接是否关闭无关紧要.将作业推送到队列后,将发送该作业(除非您终止作业过程). (3认同)

bov*_*der 5

除了丹尼尔·巴塔尔拉(Daniel Batalla)撰写的内容外,我还做了另外一项观察:deliver_later似乎执行了惰性评估,而deliver_now没有执行。

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

执行时deliver_now,访问mailer视图中@model的的reset_token属性会按预期产生重置令牌。但是,执行时deliver_later@model.reset_token总是nil。看起来好像deliver_later是用数据库数据更新模型,并且由于reset_token是数据库没有支持的附加属性,因此它将nil在此时。(对于我来说,代码文档过于嵌套,无法在源代码中进行验证。)

迈克尔deliver_now在本教程中使用。我不知道他这样做是为了避免懒惰的评估。但我花了一段时间才能认识到,我不得不改变deliver_later,以deliver_now使我的测试通过。

  • 谢谢@bovender。我只是有同样的问题。在我的模型中,有几种方法可以计算总价/总价,如果我按如下方式运行mailer,如Mailer.payment_email(model,calculate_price).deliver_later,price始终为nil。使用`deliver_now`有帮助,但是却破坏了异步传递的所有好处。为了克服这个问题,我用calculate_price.to_f替换了calculate_price,它强制进行方法评估。在其他情况下,取决于方法返回的数据类型,它可能是“ to_i”,“ to_s”等。 (2认同)