我正在使用https://github.com/Haidy777/node-youtubeAPI-simplifier从赏金 killer 的播放列表中获取一些信息。这个库的设置方式似乎是通过 Bluebird (https://github.com/petkaantonov/bluebird) 使用 Promise,我对此不太了解。查找 BlueBird 初学者指南给出 http://bluebirdjs.com/docs/beginners-guide.html这实际上只是显示了
This article is partially or completely unfinished. You are welcome to create pull requests to help completing this article.
我能够设置库
var ytapi = require('node-youtubeapi-simplifier');
ytapi.setup('My Server Key');
以及列出一些有关赏金 killer 的信息
ytdata = [];
ytapi.playlistFunctions.getVideosForPlaylist('PLCCB0BFBF2BB4AB1D')
.then(function (data) {
for (var i = 0, len = data.length; i < len; i++) {
ytapi.videoFunctions.getDetailsForVideoIds([data[i].videoId])
.then(function (video) {
console.log(video);
// ytdata.push(video); <- Push a Bounty Killer Video
});
}
});
// console.log(ytdata); This gives []
上面的代码基本上会提取完整的播放列表(根据长度,这里通常会有一些分页),然后它会从 getVideosForPlaylist
获取数据,迭代列表并为每个 YouTube 视频调用 getDetailsForVideoIds
。这里一切都很好。
从中获取数据会出现问题。我想将视频对象推送到 ytdata
数组,但不确定末尾的空数组是否是由于范围界定或某些不同步导致的,导致在 API 调用完成之前调用 console.log(ytdata)
。
我如何才能将每个赏金 killer 视频放入 ytdata
数组中以供全局使用?
最佳答案
console.log(ytdata) gets called before the API calls are finished
没错,这正是这里发生的情况,API 调用是异步的。使用异步函数后,如果要处理返回的数据,则必须采用异步方式。你的代码可以这样写:
var ytapi = require('node-youtubeapi-simplifier');
ytapi.setup('My Server Key');
// this function return a promise you can "wait"
function getVideos() {
return ytapi.playlistFunctions
.getVideosForPlaylist('PLCCB0BFBF2BB4AB1D')
.then(function (videos) {
// extract all videoIds
var videoIds = videos.map(video => video.videoId);
// getDetailsForVideoIds is called with an array of videoIds
// and return a promise, one API call is enough
return ytapi.videoFunctions.getDetailsForVideoIds(videoIds);
});
}
getVideos().then(function (ydata) {
// this is the only place ydata is full of data
console.log(ydata);
});
我在videos.map(video => video.videoId);
中使用了ES6的箭头函数,如果你的nodejs是v4+,那应该可以工作。
关于node.js - 将数据推送到 Promise 之外的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34596804/