得到一些效果很好的代码,它将检索指定播放列表中的所有项目,但需要对其进行修改,以便它可以遍历播放列表数组并检索每个列表中的所有项目。
我曾尝试在代码的不同位置放置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;
}
}
因此,需要一些有关将代码放置在播放列表数组中的位置的帮助。
答案 0 :(得分:0)
您遍历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
(如果页面多于一页),依次遍历整个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。我希望我编写的代码足够清晰,足以说明一切。如果您有任何疑问,请在评论中提问。