我正在尝试从YouTube视频中获取信息。我从看起来像这样的文件中获取ID:
songlist.json
["vbMQfaG6lo8", "07UwP3kHTTk", "gjDK4OiuIfk", "NlrK03iz74A", "E_1-oylPHjs"]
之后,我需要该文件,还需要每个ID
的数据var songlistshit = './static/js/songlistinfo.json'
var allSongs = require('./static/js/songlist.json')
for(var i = 0; i < allSongs.length; i++) {
var ytId = allSongs[i]
request("https://www.googleapis.com/youtube/v3/videos?id=" + ytId + "&key=API_KEY%20&part=snippet,contentDetails,statistics,status", function (error, response, body) {
var sd = JSON.parse(body);
var xd = sd.items[0].snippet.title
var aus = sd.items[0].snippet
name = aus.title
tn = aus.thumbnails.default.url
var data = 'n{"name": "' + name + '", "user": "Mstiekema", "img": "' + tn + '"},'
fs.appendFile(songlistshit, data, 'utf8', function(err) {if (err) {return}})
})
};
但是,当它附加到第二个JSON文件时,它会丢失原始订单。这是将其放入文件中的示例。
songlistinfo.json
{"name": "Enjoy The Silence by KI Theory (Ghost In The Shell Trailer Music)", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/E_1-oylPHjs/default.jpg"},
{"name": "Majora's Mask - Terrible Fate", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/vbMQfaG6lo8/default.jpg"},
{"name": "Lilium Elfen Lied-エルフェンリート", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/07UwP3kHTTk/default.jpg"},
{"name": "MODERN PILLOW TALKING", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/gjDK4OiuIfk/default.jpg"},
{"name": "Midna's Theme on Guitar", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/NlrK03iz74A/default.jpg"},
但不应该按此顺序进行。订单应为以下内容:
songlistinfo.json
{"name": "Majora's Mask - Terrible Fate", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/vbMQfaG6lo8/default.jpg"},
{"name": "Lilium Elfen Lied-エルフェンリート", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/07UwP3kHTTk/default.jpg"},
{"name": "MODERN PILLOW TALKING", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/gjDK4OiuIfk/default.jpg"},
{"name": "Midna's Theme on Guitar", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/NlrK03iz74A/default.jpg"},
{"name": "Enjoy The Silence by KI Theory (Ghost In The Shell Trailer Music)", "user": "Mstiekema", "img": "https://i.ytimg.com/vi/E_1-oylPHjs/default.jpg"},
(我知道songlistinfo.json文件不包含正确的JSON结构,但是我将在修复订单问题后进行修复。)
您正在写入文件中的文件,它正在按顺序写入文件,请求完成,并非所有这些都会按时完成。您可以使用救援功能而不是用于循环来解决此问题。
requestVideoInfo(0);
function requestVideoInfo(count) {
if(count < allSongs.length) {
ytId = allSongs[count]
request("https://www.googleapis.com/youtube/v3/videos?id=" + ytId + "&key=API_KEY%20&part=snippet,contentDetails,statistics,status", function (error, response, body) {
var sd = JSON.parse(body);
var xd = sd.items[0].snippet.title
var aus = sd.items[0].snippet
name = aus.title
tn = aus.thumbnails.default.url
var data = 'n{"name": "' + name + '", "user": "Mstiekema", "img": "' + tn + '"},'
fs.appendFile(songlistshit, data, 'utf8', function(err) {
if (err)
console.log('Error', e);
else
requestVideoInfo(++count);
// start to request the next video into once this one is done
})
})
}
}
但是,您可能会看到对代码的负面性能影响您不再一次拨打多个电话,并且失去了request
的回调性质。
该顺序不正确,因为您使用的异步请求不必按照您称之量的顺序完成。
例如,取决于YouTube的要求时间,您的回调可能每次都以不同的顺序运行。您必须要么使用某些库,例如bluebird和 all
方法,该方法将处理所有承诺(首先,您必须转换request
方法以返回Promise或使用Bluebird promisify
方法),然后您将获得同一响应列表订购您致电请求。
或者您可以手动创建一系列响应,毕竟将处理所有响应,您可以用一些alghoritm对其进行重新排序以具有与JSON相同的订单。
关键事实是,在循环中调用的异步函数不能与您称为它们相同的顺序解析:)