当在Guzzle中解决多个异步诺言时,我只能从第一个诺言中获得结果

时间:2018-08-22 00:41:42

标签: php asynchronous guzzle

我有以下代码,在其中创建一个Promises数组,然后对其进行结算:

$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) {
            }
          }
        }
      }
}

} }

1 个答案:

答案 0 :(得分:0)

那是因为您引用了$promise变量,并且在 all 中,这是最后的承诺。

只需稍微修改一下代码,因为您根本不需要此$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 );
        }

应以这种方式(不直接)解决/拒绝承诺,因为还可能有其他处理程序。