最近在开发一个需要频繁与多个外部API交互的项目时,我遇到了一个令人头疼的性能瓶颈。为了获取用户数据,我的PHP程序需要依次调用身份验证服务、用户画像服务和订单历史服务。由于这些都是耗时的网络请求,传统的同步调用方式意味着每个请求都必须等待上一个请求完成后才能开始,导致整个过程漫长而阻塞。用户抱怨加载缓慢,而我的代码也因为大量的嵌套回调和错误检查变得难以维护。我迫切需要一种方法来并行处理这些请求,并优雅地管理它们的最终结果。
经过一番探索,我发现了
guzzlehttp/promises
guzzlehttp/promises
安装 Guzzle Promises
使用 Composer 安装
guzzlehttp/promises
<pre class="brush:php;toolbar:false;">composer require guzzlehttp/promises
Guzzle Promises 的核心概念与实践
立即学习“PHP免费学习笔记(深入)”;
guzzlehttp/promises
Promise
then()
创建与解决承诺 (Promise)
一个
Promise
resolve()
reject()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
$promise = new Promise();
// 模拟一个异步操作,比如延迟3秒后成功
// 实际应用中,这可能是一个网络请求或文件操作
// 这里为了演示,我们手动在某个时机resolve
// $promise->resolve('Hello, asynchronous world!');
// 或者 $promise->reject('Something went wrong!');
// 我们稍后通过一个简单的定时器来模拟异步完成
// 在真实异步环境(如ReactPHP或Swoole)中,你会在I/O操作完成后调用resolve/reject
echo "操作开始,等待结果...\n";链式调用与结果传递 (then)
then()
Promise
onFulfilled
onRejected
then()
Promise
<pre class="brush:php;toolbar:false;">$promise
->then(function ($value) {
echo "Promise 成功!收到的值是: " . $value . "\n";
// 返回一个新值,这个值会传递给下一个then
return $value . " - processed.";
}, function ($reason) {
echo "Promise 失败!原因是: " . $reason . "\n";
// 如果这里不抛出异常或返回RejectedPromise,后续的then可能会转为成功路径
throw new \Exception("处理失败: " . $reason);
})
->then(function ($newValue) {
echo "第二个 then 成功!收到的值是: " . $newValue . "\n";
// 还可以返回一个新的Promise,实现更复杂的异步流程
// return new FulfilledPromise('Final result');
}, function (\Exception $e) {
echo "第二个 then 失败!捕获到异常: " . $e->getMessage() . "\n";
});
// 模拟异步操作完成
$promise->resolve('reader.'); // 尝试成功路径
// $promise->reject('Network error!'); // 尝试失败路径当你运行上述代码,你会看到
reader.
then
reject
onRejected
同步等待异步结果 (wait)
尽管
guzzlehttp/promises
wait()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
$anotherPromise = new Promise(function () use (&$anotherPromise) {
// 模拟一个耗时操作,例如从数据库获取数据
sleep(1); // 阻塞1秒
$anotherPromise->resolve('Data from DB after 1 second');
});
echo "尝试同步等待另一个 Promise 的结果...\n";
try {
$result = $anotherPromise->wait();
echo "同步等待结果: " . $result . "\n";
} catch (\Exception $e) {
echo "同步等待失败: " . $e->getMessage() . "\n";
}wait()
Promise 拒绝与错误处理
当一个 Promise 被
reject()
then()
$onRejected
onFulfilled
onRejected
RejectedPromise
onRejected
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\RejectedPromise;
$errorPromise = new Promise();
$errorPromise
->then(function ($value) {
echo "不应该走到这里: " . $value . "\n";
}, function ($reason) {
echo "第一个拒绝处理: " . $reason . "\n";
// 抛出异常,会传递给下一个onRejected
throw new \RuntimeException("处理错误时发生新错误: " . $reason);
})
->then(null, function ($e) { // 第一个参数为null,表示不处理成功情况
echo "第二个拒绝处理,捕获到异常: " . $e->getMessage() . "\n";
// 也可以返回一个新的RejectedPromise来继续传递拒绝状态
// return new RejectedPromise('Final error message');
});
$errorPromise->reject('原始操作失败!');
// 如果没有使用wait(),在非事件循环环境中,需要手动运行队列来确保回调被执行
// GuzzleHttp\Promise\Utils::queue()->run();Guzzle Promises 的优势与实际应用
onRejected
catch
otherwise
try-catch
guzzlehttp/promises
wait()
guzzlehttp/promises
总结
guzzlehttp/promises
guzzlehttp/promises
下次当你的 PHP 应用因为等待外部服务响应而变得迟缓时,不妨考虑引入
guzzlehttp/promises
以上就是如何优雅地处理PHP异步操作?GuzzlePromises助你告别回调地狱与阻塞等待的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号