public function sendAsync(RequestInterface $request, array $options = [])
    {
        // Unfortunately, the current ExponentialBackoff implementation doesn't
        // play nicely with promises.
        $retryAttempt = 0;
        $fn = function ($retryAttempt) use (&$fn, $request, $options) {
            $asyncHttpHandler = $this->asyncHttpHandler;
            $retryOptions = $this->getRetryOptions($options);
            if (!$retryOptions['calcDelayFunction']) {
                $retryOptions['calcDelayFunction'] = [ExponentialBackoff::class, 'calculateDelay'];
            }

            return $asyncHttpHandler(
                $this->applyHeaders($request),
                $this->getRequestOptions($options)
            )->then(null, function (\Exception $ex) use ($fn, $retryAttempt, $retryOptions) {
                $shouldRetry = $retryOptions['retryFunction']($ex);

                if ($shouldRetry === false || $retryAttempt >= $retryOptions['retries']) {
                    throw $this->convertToGoogleException($ex);
                }

                $delay = $retryOptions['calcDelayFunction']($retryAttempt);
                $retryOptions['delayFunction']($delay);
                $retryAttempt++;

                return $fn($retryAttempt);
            });
        };

        return $fn($retryAttempt);
    }