Метод then
Метод then класса Batch предназначен для выполнения пользовательского кода после того, как все задачи в пакетном задании (batch) успешно завершатся. Первым параметром передаётся колбэк-функция, которая получит экземпляр объекта Batch в качестве аргумента. Метод возвращает тот же экземпляр Batch, что позволяет использовать цепочки вызовов. Обычно этот метод используется вместе с методами catch и finally для обработки различных сценариев завершения пакетного задания.
Синтаксис
<?php
$batch = Bus::batch($jobs)->then(function (Batch $batch) {
// Code to be executed on success
})->dispatch();
?>
Пример
Давайте создадим пакетное задание с несколькими задачами и добавим колбэк, который будет выполняться после их успешного завершения:
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessDataJob;
use App\Jobs\SendNotificationJob;
use App\Jobs\UpdateStatusJob;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Illuminate\Http\Request;
class QueueController extends Controller
{
public function runBatch()
{
$jobs = [
new ProcessDataJob(['id' => 1]),
new ProcessDataJob(['id' => 2]),
new SendNotificationJob('User 1'),
new UpdateStatusJob('completed')
];
$batch = Bus::batch($jobs)
->then(function (Batch $batch) {
echo "Batch completed successfully";
})
->dispatch();
return $batch->id;
}
}
?>
Результат выполнения кода после завершения всех задач:
"Batch completed successfully"
Пример
Давайте используем метод then в цепочке с другими методами обработки завершения для выполнения различных действий в зависимости от результата выполнения батча:
<?php
namespace App\Console\Commands;
use App\Jobs\ImportDataJob;
use App\Jobs\GenerateReportJob;
use App\Jobs\SendEmailJob;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Illuminate\Console\Command;
use Throwable;
class RunBatchCommand extends Command
{
protected $signature = 'batch:run';
protected $description = 'Run a batch of jobs';
public function handle()
{
$jobs = [
new ImportDataJob('path/to/file.csv'),
new GenerateReportJob('daily'),
new SendEmailJob('admin@example.com')
];
$batch = Bus::batch($jobs)
->then(function (Batch $batch) {
$this->info("All jobs completed");
})
->catch(function (Batch $batch, Throwable $e) {
$this->error("Batch failed: " . $e->getMessage());
})
->finally(function (Batch $batch) {
$this->info("Batch processing finished");
})
->dispatch();
$this->info("Batch ID: " . $batch->id);
}
}
?>
Результат выполнения команды при успешном завершении всех задач:
"All jobs completed"
"Batch processing finished"
"Batch ID: batch-123456"
Пример
Давайте используем метод then для обновления данных в базе после завершения всех задач в пакетном задании:
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessOrderJob;
use App\Jobs\UpdateInventoryJob;
use App\Jobs\SendConfirmationJob;
use App\Models\Order;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
class BatchController extends Controller
{
public function processOrders()
{
$orderIds = [1, 2, 3, 4, 5];
$jobs = [];
foreach ($orderIds as $id) {
$jobs[] = new ProcessOrderJob($id);
}
$jobs[] = new UpdateInventoryJob($orderIds);
$jobs[] = new SendConfirmationJob($orderIds);
$batch = Bus::batch($jobs)
->then(function (Batch $batch) use ($orderIds) {
Order::whereIn('id', $orderIds)
->update(['status' => 'processed']);
Log::info('Batch completed', ['orders' => $orderIds]);
echo "Orders processed successfully";
})
->dispatch();
return $batch->id;
}
}
?>
Результат выполнения кода после завершения батча:
"Orders processed successfully"
Смотрите также
-
метод
catch,
который регистрирует колбэк для обработки ошибок при выполнении задач батча -
метод
finally,
который выполняется всегда после завершения батча, независимо от результата -
метод
cancel,
который отменяет выполнение пакетного задания -
метод
progress,
который возвращает информацию о прогрессе выполнения батча