我刚刚开始在Laravel 5.1中使用Jobs,我想知道从作业返回数据是否是一个好习惯?我还没有看到任何这方面的例子,但这是一个场景。让我们说它是用户之间的内部消息系统:
// Controller Method
public function store(Request $request)
{
if (!$this->messageValidator->isValid($request->all())) {
return redirect()->back()->withInput()->withErrors($this->messageValidator->getErrors());
}
$this->dispatchFrom(PostMessage::class, $request, [ 'user' => Auth::user() ]);
return redirect('messages');
}
因此,Job将获取请求数据和用户,并将执行多个任务
// In the PostMessage Job
public function handle( // dependencies here)
{
// Create a new Thread
// Add Message to the Database
// Store Recipients of Message in the Database
// Send email notifications to all involced
return $message_id;
}
在handle()方法结束时,我返回了$ message_id,因此我可以将它用于控制器中的重定向:
return view('messages.show', $message_id);
这是一种可接受的做法,还是乔布斯想以更孤立的方式执行任务?
或者也许不是对乔布斯的好用?
答案 0 :(得分:1)
通常,作业用于您可能想要排队以在后台运行的内容(异步),因此从它们接收返回值有点奇怪。
我会将数据库保存在其他位置,并仅将Job用于电子邮件通知:
// Controller Method
public function store(Request $request, MessageGuru $messageGuru)
{
if (!$this->messageValidator->isValid($request->all())) {
return redirect()->back()->withInput()
->withErrors($this->messageValidator->getErrors());
}
$messageId = $messageGuru->store($request->all());
$this->dispatchFrom(PostMessage::class, $request, [ 'user' => Auth::user() ]);
return view('messages.show', $messageId);
}
// MessageGuru
class MessageGuru {
public function store ($input) {
// Add Message to the Database
// Store Recipients of Message in the Database
}
}
// In the PostMessage Job
public function handle()
{
// Send email notifications to all involved
}
我确实检查了Laravel源代码,如果作业没有排队,确实会返回作业的返回值,但是这样使用Jobs会限制你以后将它重构为排队的作业。
答案 1 :(得分:1)
根据文档,Laravel 5 Commands被Jobs取代。这是官方的故事。非正式地仍有命令和工作。
命令扩展Command类,Job命令Job类。我自己也用它们。用于从命令行和作业到队列任务触发Laravel内容的命令。
我实际上正在寻找在排队作业运行时从排队作业中检索数据并在另一个作业中使用它的可能性。这个线程提示,命令或事件或共享对象可能会成功,但我必须自己弄清楚架构。
答案 2 :(得分:0)
我认为接受的答案不能完全回答问题……相反,它提供了一种“更好”的方法(我同意)。我想尝试回答问题本身,所以我要加2美分。
在Laravel中,您可以选择要将作业发送到的连接。
因此,您绝对可以使用默认连接来处理排队(异步)作业,这是自版本5开始的目标,并且可以将“同步”连接用于先前版本中的任何“类似于命令总线”的连接。
您甚至可以添加一个新的连接,然后将其命名为任何所需的名称(例如“总线”),并使用“同步”驱动程序,这样一来,连接会更加清晰,因此您可以区分“同步”连接,该连接用于本地测试和您要查找的命令总线。
然后,您只需指定要在分派作业时使用的连接:
ProcessPodcast::dispatch($podcast)->onConnection('bus');
有时我也会错过命令总线的想法,以及如何使用它:-)
希望这会有所帮助!
答案 3 :(得分:-1)
简答:不。
乔布斯就是这样的:一个可以在没有上下文的情况下运行的工作。你应该能够在几秒钟或一年的时间内完成一份工作。你给一份工作一些数据,它应该可以在将来的任何时候执行。
如果您需要返回数据,可以考虑在作业执行期间提出事件。如果在事情发生后需要某些值,请考虑使用命令或服务对象。