Versprechen in der AWS SDK for PHP Version 3 - AWS SDK for PHP

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Versprechen in der AWS SDK for PHP Version 3

Das AWS SDK for PHP verwendet Promises, um asynchrone Workflows zu ermöglichen, und diese Asynchronität ermöglicht es, HTTP-Anfragen gleichzeitig zu senden. Die vom SDK verwendete Promise-Spezifikation lautet Promises/A+.

Was ist ein Versprechen?

Ein Promise repräsentiert das Ergebnis einer asynchronen Operation. Der primäre Weg der Interaktion mit einem Promise ist durch seine then-Methode. Diese Methode registriert Callbacks, um entweder den möglichen Wert eines Promises oder den Grund zu erhalten, warum das Promise nicht erfüllt werden kann.

Das AWS SDK for PHP stützt sich auf das guzzlehttp/Promise-Composer-Paket für die Promise-Implementierung. Guzzle unterstützt blockierende und nicht blockierende Workflows und kann mit jeder nicht blockierenden Ereignisschleife verwendet werden.

Anmerkung

HTTP-Anfragen werden gleichzeitig im AWS SDK for PHP unter Verwendung eines einzelnen Threads gesendet, in dem nicht blockierende Aufrufe verwendet werden, um eine oder mehrere HTTP-Anfragen zu übertragen, während auf Zustandsänderungen reagiert wird (z. B. Promises erfüllen oder ablehnen).

Promises im SDK

Promises werden im gesamten SDK verwendet. Zum Beispiel werden Promise in den meisten vom SDK bereitgestellten High-Level-Abstraktionen verwendet: Umbrüche, Waiter, Befehlspools, mehrteilige Uploads, S3 Verzeichnis/Bucket-Transfers und so weiter.

Alle Clients, die das SDK bereitstellt, geben Rück-Promises, wenn Sie eine der Suffixmethoden Async aufrufen. Der folgende Code zeigt beispielsweise, wie ein Versprechen zum Abrufen der Ergebnisse eines Amazon DynamoDB DynamoDB-Vorgangs DescribeTable erstellt wird.

$client = new Aws\DynamoDb\DynamoDbClient([ 'region' => 'us-west-2', 'version' => 'latest', ]); // This will create a promise that will eventually contain a result $promise = $client->describeTableAsync(['TableName' => 'mytable']);

Beachten Sie, dass Sie entweder describeTable oderdescribeTableAsync aufrufen können. Diese Methoden sind magische __call Methoden auf einem Client, die durch das API-Modell und version Nummer mit dem Client verbunden sind. Indem Methoden wie describeTable ohne das Suffix Async aufgerufen werden, blockiert der Client, während er eine HTTP-Anfrage sendet und entweder ein Aws\ResultInterface-Objekt zurückgibt oder eine Aws\Exception\AwsException auslöst. Durch Suffix des Operationsnamens mit Async (d. h. describeTableAsync) erstellt der Client ein Promise, das schließlich mit einem Objekt Aws\ResultInterface erfüllt oder mit einer Aws\Exception\AwsException abgelehnt wird.

Wichtig

Wenn das Promise zurückgegeben wird, ist das Ergebnis möglicherweise bereits angekommen (z. B. bei Verwendung eines Mock-Handlers) oder die HTTP-Anforderung wurde möglicherweise nicht initiiert.

Sie können einen Callback mit dem Promise mit der Methode then registrieren. Diese Methode akzeptiert zwei Callbacks, $onFulfilled und $onRejected, die beide optional sind. Der Callback $onFulfilled wird aufgerufen, wenn das Promise erfüllt ist, und der Callback $onRejected wird aufgerufen, wenn das Promise abgelehnt wird (d.h. es ist fehlgeschlagen).

$promise->then( function ($value) { echo "The promise was fulfilled with {$value}"; }, function ($reason) { echo "The promise was rejected with {$reason}"; } );

Gleichzeitige Ausführung von Befehlen

Mehrere Promises können zusammen so zusammengesetzt werden, dass sie gleichzeitig ausgeführt werden. Dies kann erreicht werden, indem das SDK in eine nicht blockierende Ereignisschleife integriert wird oder indem mehrere Promises aufgebaut und darauf gewartet wird, dass sie gleichzeitig ausgeführt werden.

use GuzzleHttp\Promise\Utils; $sdk = new Aws\Sdk([ 'version' => 'latest', 'region' => 'us-east-1' ]); $s3 = $sdk->createS3(); $ddb = $sdk->createDynamoDb(); $promises = [ 'buckets' => $s3->listBucketsAsync(), 'tables' => $ddb->listTablesAsync(), ]; // Wait for both promises to complete. $results = Utils::unwrap($promises); // Notice that this method will maintain the input array keys. var_dump($results['buckets']->toArray()); var_dump($results['tables']->toArray());
Anmerkung

Das CommandPoolbietet einen leistungsfähigeren Mechanismus für die gleichzeitige Ausführung mehrerer API-Operationen.

Versprechen verketten

Einer der besten Aspekte von Promises ist, dass sie zusammensetzbar sind, sodass Sie Transformations-Pipelines erstellen können. Promise werden durch Verkettung then von Callbacks mit nachfolgenden then Callbacks zusammengestellt. Der Rückgabewert einer then-Methode ist ein Promise, das basierend auf dem Ergebnis der bereitgestellten Callbacks erfüllt oder abgelehnt wird.

$promise = $client->describeTableAsync(['TableName' => 'mytable']); $promise ->then( function ($value) { $value['AddedAttribute'] = 'foo'; return $value; }, function ($reason) use ($client) { // The call failed. You can recover from the error here and // return a value that will be provided to the next successful // then() callback. Let's retry the call. return $client->describeTableAsync(['TableName' => 'mytable']); } )->then( function ($value) { // This is only invoked when the previous then callback is // fulfilled. If the previous callback returned a promise, then // this callback is invoked only after that promise is // fulfilled. echo $value['AddedAttribute']; // outputs "foo" }, function ($reason) { // The previous callback was rejected (failed). } );
Anmerkung

Der Rückgabewert eines Zusage-Callbacks ist das Argument $value , das an Downstream-Promises übergeben wird. Wenn Sie Downstream-Promise-Ketten einen Wert bereitstellen möchten, müssen Sie einen Wert in der Callback-Funktion zurückgeben.

Ablehnung, Weiterleitung

Sie können einen Callback registrieren, der aufgerufen werden soll, wenn ein Promise abgelehnt wird. Wenn in einem Callback eine Ausnahme ausgelöst wird, wird das Promise mit der Ausnahme abgelehnt und die nächsten Promise in der Kette werden mit der Ausnahme abgelehnt. Wenn Sie einen Wert aus einem $onRejected-Callback erfolgreich zurückgeben, werden die nächsten Promises in der Promise-Kette mit dem Rückgabewert aus dem Callback $onRejected erfüllt.

Ich warte auf Versprechen

Sie können die Promises synchron erzwingen, indem Sie die wait -Methode eines Promises verwenden.

$promise = $client->listTablesAsync(); $result = $promise->wait();

Wenn beim Aufrufen der Funktion wait eines Promises eine Ausnahme auftritt, wird das Promise mit der Ausnahme abgelehnt und die Ausnahme wird ausgelöst.

use Aws\Exception\AwsException; $promise = $client->listTablesAsync(); try { $result = $promise->wait(); } catch (AwsException $e) { // Handle the error }

Der Aufruf von wait auf einem erfüllten Promise löst die Wartefunktion nicht aus. Es gibt einfach den zuvor gelieferten Wert zurück.

$promise = $client->listTablesAsync(); $result = $promise->wait(); assert($result ### $promise->wait());

Der Aufruf von wait bei einem abgelehnten Promise löst eine Ausnahme aus. Wenn der Ablehnungsgrund eine Instance von \Exception ist, wird der Grund geworfen. Andernfalls wird eine GuzzleHttp\Promise\RejectionException ausgelöst und der Grund kann durch Aufrufen der getReason-Methode der Ausnahme erhalten werden.

Anmerkung

API-Operationsaufrufe im AWS SDK for PHP werden mit Unterklassen der Klasse Aws\Exception\AwsException abgelehnt. Es ist jedoch möglich, dass der Grund, der an eine then-Methode geliefert wird, ein anderer ist, weil eine benutzerdefinierte Middleware hinzugefügt wird, die einen Ablehnungsgrund ändert.

Versprechen stornieren

Promise können mit der cancel()-Methode eines Promises abgebrochen werden. Wenn eine Zusage bereits gelöst wurde, hat der Aufruf von cancel() keine Wirkung. Das Abbrechen eines Promises löscht das Promise und alle Promises, die auf die Lieferung vom Promise warten. Ein gelöschtes Promise wird mit einer GuzzleHttp\Promise\RejectionException abgelehnt.

Versprechen kombinieren

Sie können Promise zu zusammengefassten Promises kombinieren, um anspruchsvollere Workflows zu erstellen. Das Paket guzzlehttp/promise enthält verschiedene Funktionen, mit denen Sie Promises kombinieren können.

Die API-Dokumentation für alle Funktionen zur Sammlung von Versprechen finden Sie unter namespace- GuzzleHttp .Promise.

each und each_limit

Verwenden Sie die CommandPoolOption, wenn Sie eine Aufgabenwarteschlange mit Aws\CommandInterface Befehlen haben, die gleichzeitig mit einer festen Poolgröße ausgeführt werden sollen (die Befehle können sich im Speicher befinden oder von einem Lazy-Iterator abgerufen werden). Die CommandPool stellt sicher, dass eine feste Anzahl von Befehlen gleichzeitig gesendet wird, bis der bereitgestellte Iterator erschöpft ist.

Das CommandPool funktioniert nur mit den gleichen Client-Befehlen, die ausgeführt werden. Sie können die Funktion GuzzleHttp\Promise\each_limit verwenden, um Sendebefehle verschiedener Clients gleichzeitig mit einer festen Poolgröße auszuführen.

use GuzzleHttp\Promise; $sdk = new Aws\Sdk([ 'version' => 'latest', 'region' => 'us-west-2' ]); $s3 = $sdk->createS3(); $ddb = $sdk->createDynamoDb(); // Create a generator that yields promises $promiseGenerator = function () use ($s3, $ddb) { yield $s3->listBucketsAsync(); yield $ddb->listTablesAsync(); // yield other promises as needed... }; // Execute the tasks yielded by the generator concurrently while limiting the // maximum number of concurrent promises to 5 $promise = Promise\each_limit($promiseGenerator(), 5); // Waiting on an EachPromise will wait on the entire task queue to complete $promise->wait();

Versprich Coroutinen

Eine der leistungsstärkeren Funktionen der Guzzle Promise-Bibliothek ist, dass Sie Promise-Coroutinen verwenden können, die das Schreiben von asynchronen Arbeitsabläufen mehr wie das Schreiben von traditionellen synchronen Arbeitsabläufen erscheinen lassen. Tatsächlich verwendet das AWS SDK for PHP Coroutine-Promises in den meisten Abstraktionen auf hoher Ebene.

Stellen Sie sich vor, Sie möchten mehrere Buckets erstellen und eine Datei in den Bucket hochladen, sobald der Bucket verfügbar wird. Sie möchten dies alles gleichzeitig tun, damit es so schnell wie möglich geschieht. Sie können dies leicht tun, indem Sie mehrere Coroutine-Promises mit der Funktion all() kombinieren.

use GuzzleHttp\Promise; $uploadFn = function ($bucket) use ($s3Client) { return Promise\coroutine(function () use ($bucket, $s3Client) { // You can capture the result by yielding inside of parens $result = (yield $s3Client->createBucket(['Bucket' => $bucket])); // Wait on the bucket to be available $waiter = $s3Client->getWaiter('BucketExists', ['Bucket' => $bucket]); // Wait until the bucket exists yield $waiter->promise(); // Upload a file to the bucket yield $s3Client->putObjectAsync([ 'Bucket' => $bucket, 'Key' => '_placeholder', 'Body' => 'Hi!' ]); }); }; // Create the following buckets $buckets = ['foo', 'baz', 'bar']; $promises = []; // Build an array of promises foreach ($buckets as $bucket) { $promises[] = $uploadFn($bucket); } // Aggregate the promises into a single "all" promise $aggregate = Promise\all($promises); // You can then() off of this promise or synchronously wait $aggregate->wait();