主题
#[Async]
#[Async] 属性允许操作并行运行而不排队,即使有其他请求正在进行中也会立即执行。
基本用法
将 #[Async] 属性应用于任何应并行运行的操作方法:
php
<?php // resources/views/components/post/⚡show.blade.php
use Livewire\Attributes\Async;
use Livewire\Component;
use App\Models\Post;
new class extends Component {
public Post $post;
#[Async] // [tl! highlight]
public function logActivity()
{
Activity::log('post-viewed', $this->post);
}
};blade
<div wire:intersect="logActivity">
<!-- Logs activity asynchronously when element enters viewport -->
</div>当调用 logActivity() 时,它会立即执行而不阻塞其他请求或被它们阻塞。
何时使用
对于结果不影响页面显示内容的"发送即忘"操作使用 #[Async]:
- 分析和日志记录 - 跟踪用户行为、页面浏览或交互
- 后台操作 - 触发作业、发送通知或更新外部服务
- 仅 JavaScript 结果 - 通过
await $wire.getData()获取数据,这些数据将纯粹被 JavaScript 消费
这是一个跟踪外部链接点击的示例:
php
<?php // resources/views/components/⚡external-link.blade.php
use Livewire\Attributes\Async;
use Livewire\Component;
new class extends Component {
public $url;
#[Async] // [tl! highlight]
public function trackClick()
{
Analytics::track('external-link-clicked', [
'url' => $this->url,
'user_id' => auth()->id(),
]);
}
};blade
<a href="{{ $url }}" target="_blank" wire:click="trackClick">
Visit External Site
</a>因为跟踪是异步发生的,用户的点击不会被网络请求延迟。
何时不使用
异步操作和状态修改不能混用
如果异步操作修改了反映在 UI 中的组件状态,永远不要使用它们。 因为异步操作是并行运行的,你可能会遇到不可预测的竞争条件,其中组件的状态在多个同时请求中出现分歧。
考虑这个危险的示例:
php
// Warning: This snippet demonstrates what NOT to do...
<?php // resources/views/components/⚡counter.blade.php
use Livewire\Attributes\Async;
use Livewire\Component;
new class extends Component {
public $count = 0;
#[Async] // Don't do this! [tl! highlight]
public function increment()
{
$this->count++; // State mutation in an async action [tl! highlight]
}
};如果用户快速点击递增按钮,多个异步请求会同时发出。每个请求都以相同的初始 $count 值开始,导致更新丢失。你可能点击 5 次但只看到计数器增加 1。
经验法则: 只对执行纯副作用的操作使用异步——不改变任何影响组件视图的属性的操作。
替代方法
使用 .async 修饰符
除了使用属性,你可以使用 .async 修饰符使特定的操作调用异步:
blade
<button wire:click.async="logActivity">Track Event</button>当你希望操作在某些地方是异步的但在其他地方是同步的时,这种方法很有用。
了解更多
有关异步操作、竞争条件和高级用例的更多信息,请参阅操作文档。