得到了一些工作正常的代码,并将检索指定播放列表中的所有项目,但需要修改它,以便它可以循环播放一组播放列表并检索每个列表中的所有项目。
我已经尝试在代码中的不同位置放置for-next循环但是,由于我的javascript很差,这些努力都失败了,我不知道接下来该做什么。
function onGoogleLoad() {
showhide('hidden');
getSearchParameters();
gapi.client.setApiKey(APIKEY);
gapi.client.load('youtube', 'v3', function () {
GatherVideos("", function () {
for (var i = 0; i < allVideos.length; i++) {
console.log(allVideos[i].snippet.title + " published at " + allVideos[i].snippet.publishedAt)
}
showhide('visible');
build_html(allVideos);
});
});
}
ORIGINAL CODE ...
function GatherVideos(pageToken, finished) {
var request = gapi.client.youtube.playlistItems.list({
part: 'snippet, contentDetails',
playlistId: 'UU_FksrzP3q-IuoWTiG501LQ',
maxResults: 50,
pageToken: pageToken
});
request.execute(function(response) {
allVideos = allVideos.concat(response.items);
if (!response.nextPageToken)
finished();
else
GatherVideos(response.nextPageToken, finished);
});
}
END ORIGINAL CODE
NEW CODE WITH ATTEMPT AT LOOPING ...
function GatherVideos(pageToken, finished) {
for (var p=0;p<allPlaylists.length;p++)
{
console.log('Gathering: ' + allPlaylists[p]);
var request = gapi.client.youtube.playlistItems.list({
part: 'snippet, contentDetails',
playlistId: allPlaylists[p],
maxResults: 50,
pageToken: pageToken
});
request.execute(function(response) {
console.log('Executing: ' + request);
allVideos = allVideos.concat(response.items);
if (!response.nextPageToken)
finished();
else
GatherVideos(response.nextPageToken, finished);
});
} //End for loop
}
END NEW CODE ...
function build_html(parArray) {
var n = 0;
var playlistHtml = '';
var rows = Math.floor(parArray.length / vinrow);
var rem = (allVideos.length % vinrow);
if (rem > 0) {
rows++;
}
for (var i = 0; i < rows; i++) {
playlistHtml += '<div class="row">';
for (var k = 0; k < vinrow; k++) {
if (n < parArray.length) {
playlistHtml += '<div id=' + n + ' class="col item"><img class="img-responsive fit-image" src="' +
parArray[n].snippet.thumbnails.default.url + '"><div class="vtitle">' +
parArray[n].snippet.title + '</div></div>';
n++;
} else {
playlistHtml += '<div class="col item"><div class="vtitle"> </div></div>';
}
}
playlistHtml += "</div>";
}
playlist_div.innerHTML = playlistHtml;
}
}
所以,需要一些帮助来放置代码的位置,这些代码将遍历播放列表数组。
你遍历allPlaylists
,构建请求并将其保存在request
变量中。问题是,这个循环在每次执行时都会覆盖request
变量。当您稍后调用request.execute(...)
时,您只执行最后一个请求构建(数组中的最后一个播放列表)。
您应该在for循环中移动请求执行。
for (var p = 0; p < allPlaylists.length; p++)
{
console.log('Gathering: ' + allPlaylists[p]);
var request = gapi.client.youtube.playlistItems.list({ /* ... */ });
request.execute(/* ... */);
}
以上内容已经解决了部分问题。然而,这并不能完全解决问题。你递归地调用GatherVideos
(如果有超过1页),然后再次遍历整个allPlaylists
数组。为每个播放列表设置新请求。
要解决上述问题,请从单个播放列表中检索视频,并将其移至自己的方法中。由于不同的原因,使用当前结构有点麻烦,所以我使用一种不同的方法从头开始重建它。这可能不是您正在寻找的确切答案,但我希望它会给您一些灵感:
async function listPlaylist(options = {}) {
var maxResults, pendingMaxResults, response;
options = Object.assign({}, options);
maxResults = options.maxResults;
if (Number.isInteger(maxResults) && maxResults > 0) {
// set options.maxResults to a value 1-50
options.maxResults = (maxResults - 1) % 50 + 1;
pendingMaxResults = maxResults - options.maxResults;
} else if (maxResults === "all") {
pendingMaxResults = "all";
}
response = await Promise.resolve(gapi.client.youtube.list(options));
if (response.nextPageToken && (pendingMaxResults === "all" || pendingMaxResults > 0)) {
options.maxResults = pendingMaxResults;
options.pageToken = response.nextPageToken;
return response.items.concat(await listPlaylist(options));
} else {
return response.items;
}
}
(async function () {
var playlistsVideos, videos;
// retrieve all videos of all playlists
playlistsVideos = await Promise.all(allPlaylists.map(function (playlistId) {
return listPlaylist({
id: playlistId,
part: "snippet, contentDetails",
maxResults: "all"
});
}));
// the above variable `playlistsVideos` is in the format:
// [[p1v1, p1v2, p1v3], [p2v1, p2v2, p2v3]] (p = playlist, v = video)
// this needs to be flattened to have the result you want
videos = playlistsVideos.reduce((videos, playlistVideos) => videos.concat(playlistVideos), []);
})();
我建议查看指南Using Promises并查看async
/await
的文档。以上是基于YouTube API V3。我希望我能够清楚地编写代码,让它自己说话。如果您有任何疑问,请在评论中提出。