想象一下这样的场景:你的 php 应用程序需要调用多个外部 api 来聚合数据,或者在处理用户请求时,需要同时从多个数据源获取信息。如果这些操作都是同步执行的,那么整个请求的响应时间将是所有外部调用耗时之和。这意味着,即使其中一个 api 响应很慢,你的整个应用也会被拖慢,用户只能眼睁睁地看着加载图标转圈圈。
传统的 PHP 编程模式在面对 I/O 密集型任务时显得力不从心。你可能会尝试使用
curl_multi_exec
幸运的是,PHP 社区为我们提供了一个优雅的解决方案——Promises。而
guzzlehttp/promises
要将
guzzlehttp/promises
<pre class="brush:php;toolbar:false;">composer require guzzlehttp/promises
简单来说,一个 Promise 代表了一个异步操作的最终结果。这个结果可能在未来某个时刻成功(被“履行”/Fulfilled)并带回一个值,也可能失败(被“拒绝”/Rejected)并带回一个原因(通常是一个异常)。
立即学习“PHP免费学习笔记(深入)”;
Promise 的核心交互方式是通过其
then()
then()
$onFulfilled
$onRejected
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise; $promise = new Promise(); // 注册成功和失败的回调 $promise->then( function ($value) { echo "操作成功,结果是: " . $value . PHP_EOL; }, function ($reason) { echo "操作失败,原因是: " . $reason . PHP_EOL; } ); // 模拟异步操作完成并成功 $promise->resolve('数据已获取'); // 这将触发 $onFulfilled 回调 // 或者模拟异步操作失败 // $promise->reject('API 调用失败'); // 这将触发 $onRejected 回调
链式调用与迭代解析:
guzzlehttp/promises
then()
then()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise ->then(function ($value) { // 第一个异步操作完成,返回一个新的值或Promise return "Hello, " . $value; }) ->then(function ($value) { // 第二个异步操作基于第一个的结果继续 echo $value . " from Promise!" . PHP_EOL; // 输出 "Hello, reader. from Promise!" }); $promise->resolve('reader.'); // 启动Promise链
你甚至可以在
then()
同步等待(wait()
guzzlehttp/promises
wait()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise; $promise = new Promise(function () use (&$promise) { // 模拟一个耗时操作,然后解析Promise sleep(1); // 暂停1秒 $promise->resolve('这是等待的结果'); }); echo "程序正在执行其他任务..." . PHP_EOL; $result = $promise->wait(); // 阻塞当前执行,直到Promise完成 echo "Promise 已完成,结果是: " . $result . PHP_EOL; // 输出 "这是等待的结果"
需要注意的是,
wait()
取消(cancel()
guzzlehttp/promises
与事件循环集成: 为了保持栈大小恒定,Guzzle Promises 内部使用一个任务队列异步解析。在真正的异步 PHP 环境(如基于 ReactPHP 的应用)中,你需要将这个任务队列集成到事件循环中,确保 Promise 能够被及时解析。
<pre class="brush:php;toolbar:false;">// 获取全局任务队列 $queue = GuzzleHttp\Promise\Utils::queue(); // 假设你有一个事件循环 $loop (例如 ReactPHP 的循环) // $loop->addPeriodicTimer(0, [$queue, 'run']); // 这样在每个事件循环的“tick”中,Promise 任务队列就会被处理。
通过
guzzlehttp/promises
cancel()
在实际项目中,
guzzlehttp/promises
guzzlehttp/guzzle
拥抱 Promise 模式,是 PHP 应用走向现代、高效和可伸缩的关键一步。它不仅解决了困扰开发者的异步编程难题,更让你的代码变得更加优雅和强大。
以上就是如何解决PHP异步操作的性能瓶颈,并使用GuzzlePromises提升应用效率的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号