2015-11-24 3 views
2

Я очень сильно борюсь с одной частью проекта, над которым я работаю в узле. Я начал использовать Node в первый раз несколько недель назад, поэтому я очень новичок в этом, и я не очень разбираюсь в кодировании в целом.Проблема с API Youtube, NodeJS и Promises

У меня есть библиотека под названием video.js, где я хочу получить список видео определенного плейлиста.

У меня есть функция прототипа, которая вызывается в контроллере getVideoList, который получает идентификатор списка воспроизведения вместе с некоторой другой информацией, а затем выполняет вызов API на youtube и получает результаты.

Если результатов больше 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. Обещание выполняется до завершения остальной части цикла. Если я возьму выполнение (videoList) из первой части инструкции if, то обещание не будет выполнено вообще.

Я делаю много чтения, и похоже, что 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); 
}   

ответ

1

С совместимой библиотекой Promise A + (такой как Bluebird) вы можете решить любое обещание с другим обещанием. В вашем случае решение может быть столь же просто, как:

if (result.nextPageToken){ 
    fulfill(getVideos(playlistId, apiKey, result.nextPageToken)); 
} else { 
    fulfill(videoList); 
} 

Вместо решения videoList сразу на первой странице, разрешение становится результаты следующей страницы (когда они становятся доступными), который будет разрешается по результатам страницы после этого ... и т. д., пока вы не нажмете на страницу без PageToken, и вся цепочка будет разрешена как полный список видео.

+0

Извините, что я забыл ответить вам, но спасибо за помощь, я очень этому благодарен. Я понял, что выполняю неправильно. Благодаря! –

Смежные вопросы