利用YouTube数据API,我们可以进行查询以获取属于以下请求的用户的前50个视频(通过单个查询可获得的最大结果数):https://www.googleapis.com/youtube/v3/search?key={access_key}&channelId={users_id}&part=id&order=date&maxResults=50&type=video

如果视频超过50个,则生成的JSON将具有nextPageToken字段,要获取接下来的50个视频,我们可以将&pageToken={nextPageToken}附加到上述请求中,从而产生下一个包含50个视频的页面。这可以重复,直到nextPageToken字段不再存在。

这是我使用fetch API编写的一个简单的JavaScript函数,用于获取由nextPageToken参数(或缺少参数)指定的单个视频页面。

function getUploadedVideosPage(nextPageToken) {
    return new Promise((resolve, reject) => {
        let apiUrl = 'https://www.googleapis.com/youtube/v3/search?key={access_key}&channelId={users_id}&part=id&order=date&maxResults=50&type=video';
        if(nextPageToken)
            apiUrl += '&pageToken=' + nextPageToken;

        fetch(apiUrl)
        .then((response) => {
            response.json()
            .then((data) => {
                resolve(data);
            });
        });
    });
}


现在,我们需要一个包装器函数,只要有一个getUploadedVideosPage,它就会迭代地调用nextPageToken。这是我的“工作中”,尽管很危险(稍后会详细介绍)。

function getAllUploadedVideos() {
    return new Promise((resolve, reject) => {
        let dataJoined = [];
        let chain = getUploadedVideosPage();

        for(let i = 0; i < 20000; ++i) {
            chain = chain
            .then((data) => {
                dataJoined.push(data);

                if(data.nextPageToken !== undefined)
                    return getUploadedVideosPage(data.nextPageToken);
                else
                    resolve(dataJoined);
            });
        }
    });
}


“危险”方面是for循环的条件,理论上应该是无限for(;;),因为我们没有预定义的方式来确切知道要进行多少次迭代,而终止循环的唯一方法应该是使用声明。但是,当我以这种方式实现它时,它实际上是无限的,并且永远不会终止。

因此,为什么我要对20,000次迭代进行硬编码,并且看起来可行,但是我不相信该解决方案的可靠性。我希望这里的人可以阐明如何实现没有预定义终止条件的迭代Promise链。

最佳答案

您可以使用一个可自行调用的函数来完成全部操作。

您还使用explicit promise construction anti-patternfetch()包装在new Promise中,因为fetch()已经返回了promise

function getVideos(nextPageToken, results = []) {

  let apiUrl = 'https://www.googleapis.com/youtube/v3/search?key={access_key}&channelId={users_id}&part=id&order=date&maxResults=50&type=video';
  if (nextPageToken) {
    apiUrl += '&pageToken=' + nextPageToken;
  }

  // return fetch() promise
  return fetch(apiUrl)
    .then(response => response.json())
    .then(data => {
      // merge new data into final results array
      results = results.concat(data);

      if (data.nextPageToken !== undefined) {
        // return another request promise
        return getVideos(data.nextPageToken, results);
      } else {
        // all done so return the final results
        return results
      }
    });
}

// usage
getVideos().then(results=>{/*do something with all results*/})
           .catch(err=>console.log('One of the requests failed'));

关于javascript - 以编程方式获取属于用户的所有YouTube视频,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53892304/

10-11 23:32
查看更多