2017-10-12 5 views
0

ここに私の問題があります:
Spotifyはユーザーの保存したすべてのトラックを返しません。返送するトラックの数に制限があります - 50(ここではAPIです)。guzzで複数のリクエスト


すべてのユーザーの保存されたトラックを返す解決策が見つかりました(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

これは、jsonの合計カウントを返します(1つのレコードに制限されている可能性があります)1つの最初の要求です(トラックカウントを公開するためのSpotifyの終了ポイントはありません)。これから、合計を表示するのに必要なページ数と合計に基づいて必要なリクエスト数を計算することができます。 –

答えて

1

この状態に頼らないでください。 nextのエントリがnullではないか、存在するエントリの総数を数えてtotalのエントリと比較してください。


Spotifyは、応答の周りにページネーションラッパーのエントリtotal数を公開します。最初の50件のエントリで最初の要求を行い、残りのすべてのチャンクに対して同時に要求を行うことができます。これは、その時点での合計数を知っているからです。

今後のリクエストにはasyncRequest()を使用する必要があります。これは約束を返し、残りのリクエストをすべてスケジュールします。その後、wait()インスタンスメソッドを使用して、約束を順番に待つことができます。 wait()コールの順番は関係ありません。wait()は内部イベントループをチェックし、リクエストの処理を進めるためです。さらにwait()のコールは、いずれかの方法で実行するか、すぐに解決することもできます。

URLのnextエントリに依存するのではなく、手動でURLを構築する必要があります。

私はいくつかの同時性の限界を追加することをお勧めします、Spotifyはおそらくそのためのいくつかのガイドラインを持っています。 GuzzleはそのためにPoolの実装を提供しています。