protected function getAsync(array $endpoints, $params = [])
    {
        /** @var Promise[] $promises */
        $promises = array_map(function (Endpoint $endpoint) use ($params) {
            $isCached = $this->client->getCache() && $this->client->getCache()->getItem(KeyGenerator::fromEndpoint($endpoint))->isHit();
            
            if ($endpoint->countsTowardsLimit() && !$isCached) {
                try {
                    $this->client->getMethodRateLimiter()->hit($endpoint);
                    $this->client->getAppRateLimiter()->hit($endpoint);
                } catch (RateLimitReachedException $e) {
                    return new RejectedPromise($e);
                }
            }

            return $this->client->getHttpClient()
                ->sendAsyncRequest($this->buildRequest($endpoint, $params))
                ->then(function (ResponseInterface $response) use ($endpoint) {
                    return $response
                        ->withHeader('X-Endpoint', $endpoint->getName())
                        ->withHeader('X-Request', $endpoint->getUrl())
                        ->withHeader('X-Region', $endpoint->getRegion()->getName());
                });
        }, is_array($endpoints) ? $endpoints : [$endpoints]);

        // Wait for multiple requests to complete, even if some fail
        if (count($promises) > 1) {
            $results = \GuzzleHttp\Promise\settle($promises)->wait();

            return BatchResult::fromSettledPromises($results);
        }

        // Resolve a single request
        $result = $promises[0]->wait();

        if (! $result instanceof ResponseInterface) {
            throw $result;
        }

        return Result::fromPsr7($result);
    }