我正在努力解决我在Node工作的项目的一部分问题。我几个星期前第一次开始使用Node,所以我对它非常新鲜,而且我对编码一般都不是很有经验。
我有一个名为video.js的图书馆,我想获取特定播放列表的视频列表。
我有一个在控制器中调用的原型函数getVideoList,它获取播放列表的id以及其他一些信息,然后对youtube进行API调用并获得结果。
如果结果多于50,那么在响应中将有nextPageToken属性。如果有,那么我将不得不再次进行API调用,以便获得下一页结果。 (我不认为可以在一次API调用中获取所有视频对象。)
发生的事情的一个例子:
code starts
first loop finishes
promise fulfilled
second loop starts
second loop finishes
...
meanwhile the rest of the code is already moving along to the next function (that needs to have the second loops results added to the data videolist)
截至目前,此代码执行第一个API调用,并将dataObj推送到videoList。承诺在循环的其余部分完成之前完成。如果我从if语句的第一部分中取出fulfill(videoList),则承诺根本没有实现。
我一直在做很多阅读,看起来Bluebird可能是正确的方法,但这是我的代码中唯一不能正常工作但我不知道的部分如果有必要,如果有必要,我很困惑如何在这种情况下实现它。
非常感谢任何帮助!
Videos.prototype.getVideoList = function(playlistInfo) {
var playlistId = playlistInfo.playlistId;
var videoList = [];
getVideos = function(playlistId, apiKey, nextPageToken) {
var playlistOptions = {
url: "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&maxResults=50&playlistId=" + playlistId + apiKey,
method: 'GET'
};
if (nextPageToken) {
playlistOptions.url = playlistOptions.url + '&pageToken=' + nextPageToken
}
return new Promise(function(fulfill, reject){
request(playlistOptions, function(error, results, body){
if (error) { reject(error); };
var result = JSON.parse(body);
for(var i = 0; i < result.items.length; i++){
var dataObj = {};
dataObj.videoId = result.items[i].contentDetails.videoId;
dataObj.title = result.items[i].snippet.title;
if (result.items[i].snippet.thumbnails) {
dataObj.thumbnail = result.items[i].snippet.thumbnails.default.url;
};
videoList.push(dataObj);
};
if (result.nextPageToken){
getVideos(playlistId, apiKey, result.nextPageToken);
fulfill(videoList);
} else {
fulfill(videoList);
}
})
});
}
return getVideos(this.videoTotal, playlistId, this.apiKey);
}
答案 0 :(得分:1)
使用Promise A +兼容库(例如Bluebird),您可以使用其他承诺解决任何承诺。在您的情况下,解决方案可能很简单:
if (result.nextPageToken){
fulfill(getVideos(playlistId, apiKey, result.nextPageToken));
} else {
fulfill(videoList);
}
而不是立即在第一页上解析videoList,分辨率将成为下一页(当它们变为可用时)的结果,这将通过页面后面的结果解决......等等,直到你点击没有PageToken的页面,整个链被解析为完整的videoList。