2017-10-12 107 views
0

这是我的问题:
Spotify不返回所有用户保存的曲目。返回路线的数量有限制 - 50(这里是API)。多个请求在gu 012


我找到了一个解决方案,返回所有用户保存的轨道(使用循环do-while)。它提出了很多要求(在我的例子中是〜17次 - 814首曲目),但是我的页面从6秒加载到8秒。


我读到Concurrent requests,但我不知道如何因为在我的情况下使用这个和异步请求在我的情况是没有已知的请求量。循环仅在返回轨道(项目)的计数为0时结束。您能帮我解决我的问题吗?

<?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; 
    } 
} 
+0

作为一个你可以使用的工具(afaik它没有出现Spotify有暴露轨道计数的任何终点)一个初始请求(可能限制到一个记录?),这将返回json中的总计数。由此你可以计算出所需的请求数量,根据显示全部所需的总数和页面数量。 –

回答

1

不要依赖那个条件。要么依靠next条目不是null,要么计算您拥有的总条目数,并将其与total条目进行比较。


Spotify的暴露了total数在围绕响应分页包装条目。您可以对前50个条目进行第一个请求,然后对所有剩余的块进行并发请求,因为您知道该点的总数。

你必须使用asyncRequest()作为进一步的请求,它返回一个承诺,并安排你所有的请求。然后,您可以使用wait()实例方法按顺序等待承诺。 wait()调用的顺序无关紧要,因为wait()将勾选内部事件循环并为您的任何请求取得进展。所有进一步wait()调用采取缩短运行或甚至立即解决。

不幸的是,您将不得不手动构建网址,而不能依靠您的网址的next条目。

我建议添加一些并发限制,Spotify可能有一些指导。 Guzzle为此提供了一个Pool实现。