dspym82000 2017-10-12 19:47 采纳率: 100%
浏览 127
已采纳

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 09: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.

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

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器