【问题标题】:The promise was rejected with reason: Invoking the wait callback did not resolve the promise承诺被拒绝的原因:调用等待回调没有解决承诺
【发布时间】:2020-07-22 01:51:20
【问题描述】:

我正在尝试通过 Amazon SES 及其 SDK 发送批量电子邮件。我可以看到他们使用GuzzleHttp 来表示承诺。

正在发送电子邮件,一段时间后(有时在 7 封电子邮件之后,有时在 10,000 封之后)我收到来自$promise->wait(); 的异常,并出现以下错误:

PHP 致命错误:未捕获的 GuzzleHttp\Promise\RejectionException:The 承诺被拒绝的原因:调用等待回调没有 在 ... 中解决承诺

相关堆栈跟踪:

#0 /path/to/aws/GuzzleHttp/Promise/Promise.php(75): GuzzleHttp\Promise\exception_for()
#1 /path/to/myfile.php(725): GuzzleHttp\Promise\Promise->wait()

我的代码:

function sendMassEmails($subject, $message, $recipients)
{
    $SesClient = new SesClient([
        'profile' => 'default',
        'version' => '2010-12-01',
        'region' => 'eu-central-1'
    ]);

    $sender_email = 'MyCompany <noreply@mycompany.com>';
    $char_set = 'UTF-8';
    $commands = [];

    foreach ($recipients as $recipient) {
        $commands[] = $SesClient->getCommand('SendEmail', [
            'Destination' => [
                'ToAddresses' => [$recipient],
            ],
            'ReplyToAddresses' => [$sender_email],
            'Source' => $sender_email,
            'Message' => [
                'Body' => [
                    'Html' => [
                        'Charset' => $char_set,
                        'Data' => $message,
                    ],
                    'Text' => [
                        'Charset' => $char_set,
                        'Data' => convert_html_to_text($message),
                    ],
                ],
                'Subject' => [
                    'Charset' => $char_set,
                    'Data' => $subject,
                ],
            ],
            'ConfigurationSetName' => 'MyConfigurationSetName',
        ]);
    }

    $pool = new CommandPool($SesClient, $commands, [
        'concurrency' => 2,
        'before' => function (CommandInterface $cmd, $iteratorId) {
            $a = $cmd->toArray();
            echo sprintf('About to send %d: %s' . PHP_EOL, $iteratorId, $a['Destination']['ToAddresses'][0]);
        },
        'fulfilled' => function (ResultInterface $result, $iteratorId) use ($commands) {
            // log $commands[$iteratorId]['Destination']['ToAddresses'][0]
        },
        'rejected' => function (AwsException $reason, $iteratorId) use ($commands) {
            $logData = sprintf(
                '%s | Reason: %s' . PHP_EOL,
                $commands[$iteratorId]['Destination']['ToAddresses'][0],
                $reason
            );
            // log $logData
        },
    ]);

    $promise = $pool->promise();

    $promise->wait(); // <-- this line throws the exception

    $promise->then(function () {
        // Log 'done'
    });
}

我这样调用函数:

sendMassEmails('Subject', 'Message', ['email1@example.com', 'email2@example.com', ...]);

知道为什么会这样吗?

【问题讨论】:

  • 我已经在下面给出了答案,请尝试告诉我,如果我的解决方案对您有用,我也很感兴趣。
  • 似乎沿线某处存在拒绝,导致wait()“解散”并且没有得到正确处理。如果将$promise-&gt;wait(); $promise-&gt;then(... 替换为settle($promise)-&gt;then(... 会发生什么?

标签: php aws-sdk guzzle


【解决方案1】:

wait() 方法意味着等待请求完成,即使其中一些请求失败。在代码中,我相信您已经在 CommandPool 中扩展了 EachPromise Class .
因此,您可以尝试将并发数从 2 增加到 4,这意味着现在同时发生 4 个计算,而不是之前的 2,这在我们同时处理大量请求时很好。

【讨论】:

猜你喜欢
  • 2018-04-02
  • 2015-09-27
  • 2018-11-20
  • 2020-08-14
  • 2019-04-29
  • 2018-03-19
  • 2023-03-26
  • 2014-03-12
相关资源
最近更新 更多