异步触发 Magento 事件观察器

Trigger Magento event observer asynchronously

有什么方法可以让 Magento 中的事件观察器异步吗?我想在客户下订单后在后台使用它 运行 一些耗时的脚本,但我的理解是,当事件被调度时,观察者的代码被执行 synchronously/immediately.

如@user3438533 所述,实现此目的的一种方法是在观察者触发时安排一个作业,该作业稍后可由 cron 执行。这样做是安全的,因为将来在 cron_schedule 中具有 pending 状态的作业不会被清除。

既然你提到了采购,那我们就拿它来举例吧。您需要能够 create a simple extension 才能将其付诸实践。下订单后用于执行操作的常见事件是 sales_order_place_after,因此我们将使用它来触发未来的自定义 cron 作业。

etc/config.xml

步骤 1。在config/frontend/events:

下设置事件观察器
<sales_order_place_after>
    <observers>
        <scheduleExampleJob>
            <class>My_Example_Model_Observer</class>
            <method>scheduleExampleJob</method>
        </scheduleExampleJob>
    </observers>
</sales_order_place_after>

步骤 2。设置 cron 作业处理程序,它将侦听在 config/crontab/jobs:

下的观察器中创建的新自定义作业
<my_example_job>
    <!-- @see My_Example_Model_Observer::scheduleExampleJob -->
    <run><model>My_Example_Model_Observer::runExampleJob</model></run>
</my_example_job>

Model/Observer.php

class My_Example_Model_Observer
{
    /**
     * Triggers my_example_job to get scheduled when it gets fired.
     * @param Varien_Event_Observer $observer
     * @return $this
     */
    public function scheduleExampleJob(Varien_Event_Observer $observer)
    {
        // Calculate your needed datestamp to schedule the future job.
        $scheduleAt = Mage::getModel('core/date')->timestamp('Y-m-d H:i:s', strtotime('30 minutes from now'));
        Mage::getModel('cron/schedule')
            ->setJobCode('my_example_job') // Needs to match config/crontab/jobs node
            ->setStatus(Mage_Cron_Model_Schedule::STATUS_PENDING)
            ->setScheduledAt($scheduleAt)
            ->save();
    }

    /**
     * Handler for my_example_job, executed from crontab.
     * @param $schedule
     * @return $this
     */
    public function runExampleJob($schedule)
    {
        // Do your asynchronous work!

        return $this;
    }
}