dspym82000 2017-10-12 19: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 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 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据