

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 第 3 適用於 PHP 的 AWS SDK 版中的等待程式
<a name="guide_waiters"></a>

等待程式提供抽象化方法來等待，直到資源透過輪詢資源進入特定狀態，藉此更便於實現*最終一致*的系統。您可以檢視單一版本服務用戶端的 [API 文件](https://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html)，來尋找用戶端支援的等待程式清單。若要前往該處，請前往 API 文件中的用戶端頁面，並導覽至特定版本號碼 （以日期表示），然後向下捲動至「等待」區段。[此連結會將您帶到 S3 的等待程式區段。](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#waiters)

在下列範例中，Amazon S3 用戶端用於建立儲存貯體。然後將使用等待程式來等待，直到儲存貯體存在。

```
// Create a bucket
$s3Client->createBucket(['Bucket' => 'amzn-s3-demo-bucket']);

// Wait until the created bucket is available
$s3Client->waitUntil('BucketExists', ['Bucket' => 'amzn-s3-demo-bucket']);
```

如果等待程式需要輪詢儲存貯體太多次，它將丟出一個 `\RuntimeException` 例外狀況。

## 等待程式組態
<a name="waiter-configuration"></a>

等待程式由關聯的組態選項陣列所驅動。特定等待程式使用的所有選項都有預設值，但是可能遭到覆寫以支援不同的等待策略。

您可以傳遞 `@waiter` 選項的關聯陣列到用戶端 `waitUntil()` 和 `getWaiter()` 方法的 `$args` 引數，來修改等待程式組態選項。

```
// Providing custom waiter configuration options to a waiter
$s3Client->waitUntil('BucketExists', [
    'Bucket'  => 'amzn-s3-demo-bucket',
    '@waiter' => [
        'delay'       => 3,
        'maxAttempts' => 10
    ]
]);
```

**延遲 (int)**  
輪詢嘗試間的延遲秒數。每個等待程式都有預設的 `delay` 組態值，但是您可能需要修改此設定來符合不同的使用案例。

**maxAttempts (int)**  
在等待程式失敗前可發出的最高輪詢嘗試數量。此選項可確保您不會無限期等待資源。每個等待程式都有預設的 `maxAttempts` 組態值，但是您可能需要修改此設定來符合不同的使用案例。

**initDelay (int)**  
在第一個輪詢嘗試前的等待時間 (以秒為單位)。在等待已知會需要時間進入期望狀態的資源時，這非常有幫助。

**之前 (可呼叫)**  
每次嘗試前叫用的 PHP 可呼叫功能。可呼叫操作使用將執行的 `Aws\CommandInterface` 命令以及目前已執行的嘗試數量來叫用。`before` 可呼叫操作的使用可能會在執行前或提供進度資訊前修改命令。  

```
use Aws\CommandInterface;

$s3Client->waitUntil('BucketExists', [
    'Bucket'  => 'amzn-s3-demo-bucket',
    '@waiter' => [
        'before' => function (CommandInterface $command, $attempts) {
            printf(
                "About to send %s. Attempt %d\n",
                $command->getName(),
                $attempts
            );
        }
    ]
]);
```

## 非同步等待
<a name="async-waiters"></a>

除了同步等待外，您可以叫用等待程式以在傳送其他請求或等待一次有多個資源時以非同步方式等待。

您可以使用用戶端的 `getWaiter($name, array $args = [])` 方法從用戶端擷取等待程式，以存取等待程式 promise。使用等待程式的 `promise()` 方法來啟動等待程式。等待程式承諾將以最後在等待程式中執行的 `Aws\CommandInterface` 來履行，並在發生錯誤時以 `RuntimeException` 拒絕。

```
use Aws\CommandInterface;

$waiterName = 'BucketExists';
$waiterOptions = ['Bucket' => 'amzn-s3-demo-bucket'];

// Create a waiter promise
$waiter = $s3Client->getWaiter($waiterName, $waiterOptions);

// Initiate the waiter and retrieve a promise
$promise = $waiter->promise();

// Call methods when the promise is resolved.
$promise
    ->then(function () {
        echo "Waiter completed\n";
    })
    ->otherwise(function (\Exception $e) {
        echo "Waiter failed: " . $e . "\n";
    });

// Block until the waiter completes or fails. Note that this might throw
// a \RuntimeException if the waiter fails.
$promise->wait();
```

公開以承諾為基礎的等待程式 API 可產生一些強大且相對低成本的使用案例。例如，如果您想在多個資源上等待，並且使用第一個成功解決的等待程式來執行一些動作時該怎麼做？

```
use Aws\CommandInterface;

// Create an array of waiter promises
$promises = [
    $s3Client->getWaiter('BucketExists', ['Bucket' => 'a'])->promise(),
    $s3Client->getWaiter('BucketExists', ['Bucket' => 'b'])->promise(),
    $s3Client->getWaiter('BucketExists', ['Bucket' => 'c'])->promise()
];

// Initiate a race between the waiters, fulfilling the promise with the
// first waiter to complete (or the first bucket to become available)
$any = Promise\any($promises)
    ->then(function (CommandInterface $command) {
        // This is invoked with the command that succeeded in polling the
        // resource. Here we can know which bucket won the race.
        echo "The {$command['Bucket']} waiter completed first!\n";
    });

// Force the promise to complete
$any->wait();
```