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
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();