最近在开发一个需要频繁与多个外部API进行交互的项目时,我遇到了一个典型的性能瓶颈。为了获取一个完整的用户视图,我需要分别请求用户基本信息、订单历史和个性化推荐。如果这些请求一个接一个地执行,整个页面加载时间会非常长,用户体验极差。我尝试将它们并行化,但很快就陷入了传统PHP异步处理的噩梦——多层嵌套的回调函数。
代码变得像意大利面条一样难以理解,错误处理也变得异常复杂。任何一个api请求失败,都会导致整个流程中断,而且很难追踪是哪个环节出了问题。我迫切需要一种更清晰、更可控的方式来管理这些“未来”的结果。
Composer在线学习地址:学习地址
正当我为此苦恼时,我发现了
guzzlehttp/promises
第一步:通过 Composer 安装
如果你还没有安装 Composer,可以访问其官方网站获取安装指南。安装好 Composer 后,在你的项目根目录下运行以下命令:
立即学习“PHP免费学习笔记(深入)”;
<pre class="brush:php;toolbar:false;">composer require guzzlehttp/promises
这条命令会自动下载
guzzlehttp/promises
vendor
composer.json
那么,
guzzlehttp/promises
1. 什么是 Promise?
简单来说,一个 Promise(承诺)代表了一个异步操作的最终结果。这个结果可能在未来某个时间点成功(
fulfilled
rejected
pending
2. then()
Promise 的核心在于其
then()
then()
onFulfilled
onRejected
then()
让我们看一个简单的例子:
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
$promise = new Promise();
$promise
->then(function ($value) {
echo "第一步:收到了值 - " . $value . "\n";
// 返回一个新值,这个值会传递给下一个 then
return "Hello, " . $value;
})
->then(function ($value) {
echo "第二步:处理了新值 - " . $value . "!\n";
// 返回一个 Promise,下一个 then 会等待这个 Promise 完成
$nextPromise = new Promise();
// 模拟一个异步操作,稍后解决
// 实际应用中,这里可能是另一个 API 请求
// 比如:setTimeout(function() use ($nextPromise) { $nextPromise->resolve('World'); }, 100);
$nextPromise->resolve('World');
return $nextPromise;
})
->then(function ($value) {
echo "第三步:最终结果 - " . $value . "\n";
});
// 解决第一个 Promise,触发链式回调
$promise->resolve('Reader');
// 输出:
// 第一步:收到了值 - Reader
// 第二步:处理了新值 - Hello, Reader!
// 第三步:最终结果 - World在这个例子中,我们创建了一个 Promise。当它被
resolve('Reader')then
then
then
Promise
then
Promise
3. 优雅的错误处理:reject()
otherwise()
当异步操作失败时,我们可以使用
reject($reason)
onRejected
otherwise()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
$promise = new Promise();
$promise
->then(function ($value) {
echo "成功回调,但这里将拒绝: " . $value . "\n";
throw new \Exception('Oops, something went wrong!'); // 抛出异常会拒绝 Promise
})
->otherwise(function ($reason) { // 专门用于处理拒绝的回调
echo "捕获到错误: " . $reason->getMessage() . "\n";
// 你可以选择返回一个值,让后续链条恢复正常
// return "错误已处理,继续前进!";
})
->then(function ($value) {
echo "如果前面错误被处理并返回了值,这里会执行:" . $value . "\n";
});
$promise->resolve('数据');
// 输出:
// 成功回调,但这里将拒绝: 数据
// 捕获到错误: Oops, something went wrong!otherwise()
4. 同步等待与取消
虽然 Promise 主要用于异步场景,但有时我们可能需要强制等待一个 Promise 完成并获取其结果。
wait()
<pre class="brush:php;toolbar:false;">use GuzzleHttp\Promise\Promise;
$promise = new Promise(function () use (&$promise) {
// 模拟一个耗时操作
sleep(1);
$promise->resolve('等待的结果');
});
echo "开始等待...\n";
$result = $promise->wait(); // 会阻塞直到 Promise 完成
echo "等待结束,结果是:" . $result . "\n";
// 你也可以通过 cancel() 方法尝试取消一个尚未完成的 Promise
$cancellablePromise = new Promise(null, function () {
echo "Promise 被取消了!\n";
// 在这里执行清理操作
});
$cancellablePromise->cancel(); // 尝试取消使用 Composer 和
guzzlehttp/promises
otherwise()
通过引入
guzzlehttp/promises
以上就是告别回调地狱:如何用Composer和GuzzlePromises优雅处理PHP异步操作的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号