修复超链接
相关信息:
- 类型:文档文章
- 文章: 事件系统
- 文档: 《Laravel 8 中文文档(8.5)》
此投稿已在 2年前 合并。
内容修改:
Old | New | Differences |
---|---|---|
1 | ||
2 | 1 | # 事件 |
3 | 2 | |
4 | - [介绍](# | |
5 | - [注册事件和监听器](# | |
6 | - [生成事件和监听器](# | |
7 | - [手动注册事件](# | |
8 | - [发现事件](# | |
9 | - [定义事件](# | |
10 | - [定义监听器](# | |
11 | - [队列中的时间和监听器](# | |
12 | - [手动与队列交互](# | |
13 | - [队列中的事件和监听器以及数据库交互](# | |
14 | - [处理失败的任务](# | |
15 | - [触发事件](# | |
16 | - [事件订阅者](# | |
17 | - [构建事件订阅者](# | |
18 | - [注册事件订阅者](# | |
3 | - [介绍](#introduction) | |
4 | - [注册事件和监听器](#registering-events-and-listeners) | |
5 | - [生成事件和监听器](#generating-events-and-listeners) | |
6 | - [手动注册事件](#manually-registering-events) | |
7 | - [发现事件](#event-discovery) | |
8 | - [定义事件](#defining-events) | |
9 | - [定义监听器](#defining-listeners) | |
10 | - [队列中的时间和监听器](#queued-event-listeners) | |
11 | - [手动与队列交互](#manually-interacting-with-the-queue) | |
12 | - [队列中的事件和监听器以及数据库交互](#queued-event-listeners-and-database-transactions) | |
13 | - [处理失败的任务](#handling-failed-jobs) | |
14 | - [触发事件](#dispatching-events) | |
15 | - [事件订阅者](#event-subscribers) | |
16 | - [构建事件订阅者](#writing-event-subscribers) | |
17 | - [注册事件订阅者](#registering-event-subscribers) | |
19 | 18 | |
20 | 19 | <a name="introduction"></a> |
21 | 20 | ## 介绍 | … | … |
23 | 22 | |
24 | 23 | 事件系统可以作为一个非常棒的方式来解耦你的系统的方方面面,因为一个事件可以有多个完全不相关的监听者.例如,你希望每当有订单发出的时候都给你发送一个Slack通知. 你大可不必将你的处理订单的代码和发送slack消息的代码放在一起, 你只需要触发一个 `App\Events\OrderShipped` 事件, 然后事件监听者可以收到这个事件然后发送slack通知 |
25 | 24 | |
26 | <a name=" | |
25 | <a name="registering-events-and-listeners"></a> | |
27 | 26 | ## 注册事件和监听器 |
28 | 27 | |
29 | 28 | 在系统的服务提供者 `App\Providers\EventServiceProvider` 中提供了一个简单的方式来注册你所有的事件监听者. 属性 `listen` 包含所有的事件(作为键) 和对应的监听器(值). 你可以添加任意多系统需要的监听器在这个数组中, 让我们添加一个 `OrderShipped` 事件 | … | … |
44 | 43 | |
45 | 44 | > 技巧:可以用Artisan 命令行 `event:list` 来显示系统注册的事件和监听器的列表。 |
46 | 45 | |
47 | ||
48 | ||
46 | ||
47 | ||
49 | 48 | <a name="generating-events-and-listeners"></a> |
50 | 49 | ### 生成事件和监听器 |
51 | 50 | … | … |
112 | 111 | // |
113 | 112 | })->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10))); |
114 | 113 | |
115 | ||
116 | ||
114 | ||
115 | ||
117 | 116 | 如果你想处理匿名队列侦听器失败,你可以在定义`queueable`侦听器时为 `catch `方法提供一个闭包。这个闭包将接收导致侦听器失败的事件实例和` Throwable`实例: |
118 | 117 | ```php |
119 | 118 | use App\Events\PodcastProcessed; | … | … |
160 | 159 | } |
161 | 160 | ``` |
162 | 161 | |
163 | ||
164 | ||
162 | ||
163 | ||
165 | 164 | 事件发现在默认情况下是禁用的,但是你可以通过覆盖应用程序的 `EventServiceProvider`的`shouldDiscoverEvents`方法来启用它: |
166 | 165 | ```php |
167 | 166 | /** | … | … |
231 | 230 | } |
232 | 231 | ``` |
233 | 232 | |
234 | ||
235 | ||
233 | ||
234 | ||
236 | 235 | 如您所见,这个事件类不包含逻辑。它是一个被购买的 `App\Models\Order` 实例容器。 如果事件对象是使用 PHP 的 `SerializesModels` 函数序列化的,事件使用的 `SerializesModels` trait 将会优雅地序列化任何 Eloquent 模型, 比如在使用 [队列侦听器](#queued-event-listeners) 时。 |
237 | 236 | |
238 | 237 | <a name="defining-listeners"></a> | … | … |
282 | 281 | |
283 | 282 | 如果侦听器执行缓慢的任务如发送电子邮件或发出 HTTP 请求,你可以将任务丢给队列处理。在开始使用队列监听器之前,请确保在你的服务器或者本地开发环境中能够 [配置队列](/docs/laravel/8.5/queues) 并启动一个队列监听器。 |
284 | 283 | |
285 | ||
286 | ||
284 | ||
285 | ||
287 | 286 | 要指定监听器启动队列,你可以在监听器类中实现 `ShouldQueue` 接口。由 Artisan 命令 `event:generate` 生成的监听器已经将此接口导入到当前命名空间中,因此你可以直接使用: |
288 | 287 | |
289 | 288 | <?php | … | … |
348 | 347 | return 'listeners'; |
349 | 348 | } |
350 | 349 | |
351 | ||
352 | ||
353 | <a name=" | |
350 | ||
351 | ||
352 | <a name="conditionally-queueing-listeners"></a> | |
354 | 353 | #### 条件监听队列 |
355 | 354 | |
356 | 355 | 有时,您可能需要根据一些仅在运行时可用的数据来确定侦听器是否应该排队。为此,可以将`shouldQueue`方法添加到侦听器中,以确定侦听器是否应该排队。如果`shouldQueue`方法返回`false`,则侦听器将不会执行: | … | … |
389 | 388 | } |
390 | 389 | } |
391 | 390 | ``` |
392 | <a name=" | |
391 | <a name="manually-interacting-with-the-queue"></a> | |
393 | 392 | ### 手动访问队列 |
394 | 393 | |
395 | 394 | 如果你需要手动访问监听器下面队列任务的 `delete`和`release`方法,可以使用`illighte\queue\interactiswithqueue`trait进行访问。默认情况下,此trait在生成的侦听器上导入,并提供对以下方法的访问: | … | … |
420 | 419 | } |
421 | 420 | } |
422 | 421 | ``` |
423 | <a name=" | |
422 | <a name="queued-event-listeners-and-database-transactions"></a> | |
424 | 423 | ### 排队事件侦听器和数据库事务 |
425 | 424 | |
426 | 425 | 当在数据库事务中调度排队的侦听器时,它们可能会在提交数据库事务之前由队列进行处理。发生这种情况时,您在数据库事务期间对模型或数据库记录所做的任何更新可能尚未反映在数据库中。此外,在事务中创建的任何模型或数据库记录可能不存在于数据库中。如果侦听器依赖于这些模型,则在处理分派排队侦听器的作业时,可能会发生意外错误. |
427 | 426 | |
428 | ||
429 | ||
427 | ||
428 | ||
430 | 429 | 如果队列连接的`after_commit`配置选项设置为`false`,则仍然可以通过在侦听器类上定义`$afterCommit`属性来指示在提交所有打开的数据库事务之后应调度特定的队列侦听器: |
431 | 430 | ```php |
432 | 431 | <?php | … | … |
445 | 444 | ``` |
446 | 445 | > 技巧:要了解有关解决这些问题的更多信息,请查看有关 [队列任务和数据库事务](/docs/laravel/8.x/queues#jobs-and-database-transactions). |
447 | 446 | |
448 | <a name=" | |
447 | <a name="handling-failed-jobs"></a> | |
449 | 448 | ### 处理失败的队列 |
450 | 449 | |
451 | 450 | 有时队列的事件侦听器可能会失败。如果排队的侦听器超过了队列工作者定义的最大尝试次数,则将对侦听器调用`failed`方法。`failed`方法接收导致失败的事件实例和`Throwable`: | … | … |
486 | 485 | } |
487 | 486 | } |
488 | 487 | ``` |
489 | <a name=" | |
488 | <a name="specifying-queued-listener-maximum-attempts"></a> | |
490 | 489 | #### 指定队列侦听器的最大尝试次数 |
491 | 490 | |
492 | 491 | 如果队列中的某个侦听器遇到错误,您可能不希望它无限期地重试。因此,Laravel提供了各种方法来指定侦听器的尝试次数或尝试时间。 | … | … |
513 | 512 | public $tries = 5; |
514 | 513 | } |
515 | 514 | ``` |
516 | ||
517 | ||
515 | ||
516 | ||
518 | 517 | 作为定义侦听器在失败之前可以尝试多少次的替代方法,您可以定义不再尝试侦听器的时间。这允许在给定的时间范围内尝试多次监听。若要定义不再尝试监听器的时间,请在您的监听器类中添加 `retryUntil` 方法。此方法应返回一个 `DateTime` 实例: |
519 | 518 | |
520 | 519 | /** | … | … |
605 | 604 | } |
606 | 605 | } |
607 | 606 | |
608 | ||
609 | ||
607 | ||
608 | ||
610 | 609 | <a name="registering-event-subscribers"></a> |
611 | 610 | ### 注册事件订阅者 |
612 | 611 | … | … |
639 | 638 | UserEventSubscriber::class, |
640 | 639 | ]; |
641 | 640 | } |
641 | ||
642 | 642 | |
643 |