【问题标题】:For loop doesn't append to other json in original orderFor循环不会以原始顺序附加到其他json
【发布时间】:2017-04-19 05:11:57
【问题描述】:

我正在尝试从 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 结构,但我会在修复顺序问题后修复它。)

【问题讨论】:

  • 您可能希望删除 url 中包含 api 键的部分。

标签: javascript json node.js youtube-api


【解决方案1】:

您正在异步写入文件,它按照请求完成的顺序写入文件,并非所有请求都会按时完成。您可以通过使用递归函数而不是 for 循环来解决此问题。

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 的回调性质的好处。

【讨论】:

    【解决方案2】:

    该顺序可能不正确,因为您使用的异步请求不必按照您调用它们的顺序完成。

    例如,根据对 youtube 的请求时间,您的回调可能每次都以不同的顺序运行。您必须使用诸如 Bluebird 之类的库和 all 方法来处理所有承诺(首先您必须转换 request 方法以返回承诺或使用 Bluebird promisify 方法),然后您将获得与您调用请求的顺序相同的响应列表。

    或者您可以手动创建一个响应数组,在处理完所有响应后,您可以使用一些算法对它们重新排序,使其具有与 JSON 相同的顺序。

    关键的事实是循环中调用的异步函数不能保证按照你调用它们的顺序解析:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      相关资源
      最近更新 更多