插件窝 干货文章 高效的异步操作:Guzzle Promises 的实践与应用

高效的异步操作:Guzzle Promises 的实践与应用

Promise 异步 Client Promises 193    来源:    2025-03-13

Guzzle 是一个功能强大的 PHP HTTP 客户端,广泛用于发送 HTTP 请求。Guzzle Promises 是 Guzzle 提供的一个异步操作库,允许开发者以非阻塞的方式处理 HTTP 请求和其他异步任务。通过使用 Guzzle Promises,可以显著提高应用程序的性能和响应速度。

1. Guzzle Promises 的基本概念

Guzzle Promises 提供了一种处理异步操作的方式,类似于 JavaScript 中的 Promise。它允许你在异步操作完成时执行回调函数,而不需要阻塞主线程。

  • Promise:表示一个异步操作的结果,可以是成功(fulfilled)、失败(rejected)或等待中(pending)。
  • Fulfilled:表示异步操作成功完成,并返回了结果。
  • Rejected:表示异步操作失败,并返回了错误信息。
  • Pending:表示异步操作仍在进行中。

2. 使用 Guzzle Promises 进行异步操作

2.1 创建 Promise

你可以使用 GuzzleHttp\Promise\Promise 类来创建一个 Promise 对象。

use GuzzleHttp\Promise\Promise;

$promise = new Promise();
$promise->then(
    function ($value) {
        // 成功时的回调
        echo "Success: $value";
    },
    function ($reason) {
        // 失败时的回调
        echo "Failure: $reason";
    }
);

// 模拟异步操作完成
$promise->resolve('Hello, World!');
// 或者模拟异步操作失败
// $promise->reject('Something went wrong!');

2.2 使用 Guzzle 发送异步 HTTP 请求

Guzzle 提供了 requestAsync 方法,可以发送异步 HTTP 请求并返回一个 Promise 对象。

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client();

$promise1 = $client->requestAsync('GET', 'https://api.example.com/endpoint1');
$promise2 = $client->requestAsync('GET', 'https://api.example.com/endpoint2');

$promise1->then(
    function ($response) {
        echo "Response 1: " . $response->getBody();
    },
    function ($reason) {
        echo "Request 1 failed: " . $reason;
    }
);

$promise2->then(
    function ($response) {
        echo "Response 2: " . $response->getBody();
    },
    function ($reason) {
        echo "Request 2 failed: " . $reason;
    }
);

// 等待所有 Promise 完成
Promise\Utils::settle([$promise1, $promise2])->wait();

2.3 并行处理多个异步请求

Guzzle Promises 提供了 Promise\Utils 工具类,可以方便地处理多个异步请求。

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client();

$promises = [
    'request1' => $client->requestAsync('GET', 'https://api.example.com/endpoint1'),
    'request2' => $client->requestAsync('GET', 'https://api.example.com/endpoint2'),
];

$results = Promise\Utils::settle($promises)->wait();

foreach ($results as $key => $result) {
    if ($result['state'] === 'fulfilled') {
        echo "$key succeeded: " . $result['value']->getBody() . "\n";
    } elseif ($result['state'] === 'rejected') {
        echo "$key failed: " . $result['reason']->getMessage() . "\n";
    }
}

3. 高级用法

3.1 Promise 链

你可以通过 then 方法将多个 Promise 链接在一起,形成一个 Promise 链。

$promise = $client->requestAsync('GET', 'https://api.example.com/endpoint1');

$promise
    ->then(function ($response) {
        // 第一个请求成功后的处理
        return $response->getBody();
    })
    ->then(function ($body) use ($client) {
        // 使用第一个请求的结果发起第二个请求
        return $client->requestAsync('POST', 'https://api.example.com/endpoint2', [
            'body' => $body
        ]);
    })
    ->then(function ($response) {
        // 第二个请求成功后的处理
        echo "Second request succeeded: " . $response->getBody();
    })
    ->otherwise(function ($reason) {
        // 任何一个请求失败时的处理
        echo "Request failed: " . $reason;
    });

3.2 超时处理

你可以使用 Promise\Utils::settlePromise\Utils::all 来处理超时。

use GuzzleHttp\Promise;

$promises = [
    $client->requestAsync('GET', 'https://api.example.com/endpoint1'),
    $client->requestAsync('GET', 'https://api.example.com/endpoint2'),
];

$results = Promise\Utils::settle($promises)->wait();

foreach ($results as $result) {
    if ($result['state'] === 'fulfilled') {
        echo "Request succeeded: " . $result['value']->getBody() . "\n";
    } elseif ($result['state'] === 'rejected') {
        echo "Request failed: " . $result['reason']->getMessage() . "\n";
    }
}

4. 总结

Guzzle Promises 提供了一种高效的方式来处理异步操作,特别是在处理多个 HTTP 请求时。通过使用 Promise,你可以避免阻塞主线程,提高应用程序的性能和响应速度。掌握 Guzzle Promises 的使用,可以帮助你更好地构建高性能的 PHP 应用程序。