dspym82000 2017-10-12 11:47 采纳率: 100%
浏览 128
已采纳

guzzle多次请求

Here is my problem:
Spotify doesn't return all user's saved tracks. There is limit for count of returning tracks - 50 (here is API).


I found a solution that returns all user's saved track (used loop do-while). It makes a lot of requests (in my case was ~17 times - 814 tracks) But my page loads from 6 secs to 8 secs.


I read about Concurrent requests but I don't know how to use this and async requests in my situation because in my case is no known amount of requests. The loop ends only when count of returning tracks(items) are 0. Can you help me with my problem?

<?php

namespace AppBundle\Service;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class SpotifyRequester
{
    protected $client;

    protected $tokenStorage;

    public function __construct(TokenStorageInterface $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
        $this->client = new Client();
    }

    public function getSavedTracks()
    {
        $token = $this->getToken(); // true token

        $offset = 0;
        do {
            $response = $this->client->request('GET',
                'https://api.spotify.com/v1/me/tracks?limit=50&offset=' . $offset, [
                    'headers' => [
                        'Authorization:' => 'Bearer ' . $token,
                        'Accept:' => 'application/json',
                        'Content-Type:' => 'application/json',
                    ]
                ]);
            // Response from current request
            $content = json_decode($response->getBody()->getContents(), true);
            $offset += count($content['items']);
        }
        while (count($content['items']) != 0);
        // Count of tracks
        return $offset;
    }
}

展开全部

  • 写回答

1条回答 默认 最新

  • dongyu5482 2017-10-13 01:50
    关注

    Don't rely on that condition. Either rely on the next entry not being null or count the total entries you have and compare it to the total entry.


    Spotify exposes a total number of entries in the pagination wrapper around the response. You can make a first request with the first 50 entries, then make concurrent requests for all remaining chunks, because you know the total number at that point.

    You have to use asyncRequest() for the further requests, which returns a promise, and schedule all your remaining requests. Then you can wait for the promises sequentially using the wait() instance method. The order of your wait() calls doesn't matter, because wait() will tick the internal event loop and make progress for any of your requests. All further wait() calls take either way shorter to run or even resolve immediately.

    Unfortunately, you will have to construct the URLs manually, instead of being able to rely on the next entry for your URLs.

    I'd recommend to add some limit of concurrency, Spotify probably has some guidelines for that. Guzzle offers a Pool implementation for that.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部