Action Job / Mailer的`deliver_now`和`deliver_later`之间的区别
在Rails中与ActionJob
连接的常见模式是使用perform()
方法设置Job,该方法通过perform_now
或perform_later
异步调用
在Mailers的特例中,您可以直接调用deliver_now
或deliver_later
因为ActionJob
与ActionMailer
很好地集成在一起。
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_now
和deliver_later
之间的真正区别是什么? 一个不是异步的吗?
同样,相同的差异适用于perform_now
和perform_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
,访问邮件程序视图中的@model
的reset_token
属性会产生预期的重置令牌。 但是,在执行deliver_later
, @model.reset_token
总是nil
。 似乎deliver_later
使用数据库数据更新模型,并且因为reset_token
是数据库不支持的附加属性,所以此时它将nil
。 (代码文档嵌套得太深,我无法在源代码中validation这一点。)
Michael在教程中使用了deliver_now
。 我不知道他这样做是为了避免懒惰的评价。 但我花了一段时间才意识到我只需要将deliver_now
更改为deliver_now
以使我的测试通过。