При выполнении нескольких асинхронных обещаний в Guzzle я могу получить результат только от первого обещания

У меня есть следующий код, в котором я создаю массив обещаний, а затем устанавливаю их:

$processed = $this->process_pins( $pins->data, $board_id );
foreach ( $processed as $key => $result ) {
        var_dump($result);;
}

public function process_pins( array $pins, int $wp_id ) {

    $credentials = new Credentials( AMAZON_ACCESS_KEY, AMAZON_ACCESS_SECRET );

    $client = new LambdaClient( [
        'version'     => 'latest',
        'region'      => AMAZON_ACCESS_REGION,
        'credentials' => $credentials,
    ] );

    $promises = [];

    foreach ( $pins as $pin ) {
        $promise = $client->invokeAsync( [
            // The name your created Lambda function
            'FunctionName' => 'processRekognition',
            'Payload'      => json_encode( [ 'image_url' => $pin->image->original->url ] ),
        ] );
        $promise->then(
            function ( $result ) use ( $wp_id, $pin, &$promise ) {
                $meta                   = get_post_meta( $wp_id, $pin->id, true );
                $meta['status']         = PIN_PROCESSING_STATUS_COMPLETE;
                $meta['processed_data'] = wp_json_encode( (string) $result->get( 'Payload' ) );
                update_post_meta( $wp_id, $pin->id, $meta );
                $promise->resolve( (string) $result->get( 'Payload' ) );
            },
            function ( $reason ) use ( $wp_id, $pin, &$promise ) {
                $meta                   = get_post_meta( $wp_id, $pin->id, true );
                $meta['status']         = PIN_PROCESSING_STATUS_ERROR;
                $meta['processed_data'] = $reason;
                update_post_meta( $wp_id, $pin->id, $meta );
                $promise->reject( $reason );
            }
        );

        $promises[ $pin->id ] = $promise;
    }

    return Promise\settle( $promises )->wait();
}

Я ожидал, что $result всегда будет массивом со «stat» и «value», но я получаю это только для первого результата, все остальные являются объектами Response.

Вот что показано в var_dump:

array(2) {
  ["state"]=>
  string(9) "fulfilled"
  ["value"]=>
  string(94) "["tag1","tag2","https://i.pinimg.com/originals/3e/b2/f0/3eb2f0fbb5d7f357bf9c7f8363957cc6.png"]"
}
array(2) {
  ["state"]=>
  string(9) "fulfilled"
  ["value"]=>
  object(Aws\Result)#1028 (1) {
    ["data":"Aws\Result":private]=>
    array(6) {
      ["Payload"]=>
      object(GuzzleHttp\Psr7\Stream)#1209 (7) {
        ["stream":"GuzzleHttp\Psr7\Stream":private]=>
        resource(85) of type (stream)
        ["size":"GuzzleHttp\Psr7\Stream":private]=>
        NULL
        ["seekable":"GuzzleHttp\Psr7\Stream":private]=>
        bool(true)
        ["readable":"GuzzleHttp\Psr7\Stream":private]=>
        bool(true)
        ["writable":"GuzzleHttp\Psr7\Stream":private]=>
        bool(true)
        ["uri":"GuzzleHttp\Psr7\Stream":private]=>
        string(10) "php://temp"
        ["customMetadata":"GuzzleHttp\Psr7\Stream":private]=>
        array(0) {
        }
      }
      ["StatusCode"]=>
      int(200)
      ["FunctionError"]=>
      string(0) ""
      ["LogResult"]=>
      string(0) ""
      ["ExecutedVersion"]=>
      string(7) "$LATEST"
      ["@metadata"]=>
      array(4) {
        ["statusCode"]=>
        int(200)
        ["effectiveUri"]=>
        string(90) "https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/processRekognition/invocations"
        ["headers"]=>
        array(8) {
          ["date"]=>
          string(29) "Wed, 22 Aug 2018 00:35:24 GMT"
          ["content-type"]=>
          string(16) "application/json"
          ["content-length"]=>
          string(2) "94"
          ["connection"]=>
          string(10) "keep-alive"
          ["x-amzn-requestid"]=>
          string(36) "424350ab-a5a3-11e8-95f4-6d4c60dd39bb"
          ["x-amzn-remapped-content-length"]=>
          string(1) "0"
          ["x-amz-executed-version"]=>
          string(7) "$LATEST"
          ["x-amzn-trace-id"]=>
          string(50) "root=1-5b7cafcc-613f1f7fec4d9ca77ad86773;sampled=0"
        }
        ["transferStats"]=>
        array(1) {
          ["http"]=>
          array(1) {
            [0]=>
            array(0) {
            }
          }
        }
      }
}

} }

Спасибо, этот вопрос помог мне понять и решить мою проблему.

aviboy2006 26.11.2020 13:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
1
759
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это потому, что вы берете переменную $promise по ссылке, а в все ваших замыканий это будет последнее обещание.

Просто немного измените код, потому что этот $promise вам совсем не нужен:

        function ( $result ) use ( $wp_id, $pin ) {
            $meta                   = get_post_meta( $wp_id, $pin->id, true );
            $meta['status']         = PIN_PROCESSING_STATUS_COMPLETE;
            $meta['processed_data'] = wp_json_encode( (string) $result->get( 'Payload' ) );
            update_post_meta( $wp_id, $pin->id, $meta );
            return (string) $result->get( 'Payload' );
        },
        function ( $reason ) use ( $wp_id, $pin ) {
            $meta                   = get_post_meta( $wp_id, $pin->id, true );
            $meta['status']         = PIN_PROCESSING_STATUS_ERROR;
            $meta['processed_data'] = $reason;
            update_post_meta( $wp_id, $pin->id, $meta );
            return \GuzzleHttp\Promise\rejection_for( $reason );
        }

Обещание должно быть разрешено / отклонено таким образом (не напрямую), потому что могут быть и другие обработчики.

Другие вопросы по теме