【发布时间】:2019-05-22 08:52:38
【问题描述】:
利用 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);
});
});
});
}
现在我们需要一个包装函数,只要我们有一个nextPageToken,它就会迭代地调用getUploadedVideosPage。这是我的“工作”,虽然很危险(稍后会详细介绍)。
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(;;) 因为我们没有预定义的方法来确切知道要进行多少次迭代,并且终止循环的唯一方法应该是resolve 声明。然而,当我以这种方式实现它时,它确实是无限的并且永远不会终止。
因此,我为什么要硬编码 20,000 次迭代,它似乎可以工作,但我不相信这个解决方案的可靠性。我希望这里有人可以阐明如何实现这个没有预定义终止条件的迭代 Promise 链。
【问题讨论】:
-
return调用后解决? -
将
resolve(dataJoined);更改为return resolve(dataJoined);并没有解决它陷入无限循环的问题。 -
为什么你有一个 for 循环?仅仅让递归做它的事情还不够吗?
-
我推测递归可能是要走的路,不幸的是我的递归技能“生疏”。如果您能证明递归方法,我将非常感激。
-
对不起,如果我之前的评论含糊不清。我得到的是,我希望 getUploadedVideosPage 将返回页面的结果,并与使用下一页令牌调用 getUploadedVideosPage 的剩余结果相连接。没有循环。只是 getUploadedVideosPage 在 thenable 中调用自己。
标签: javascript es6-promise youtube-data-api