2016-01-04 49 views
0

我使用https://github.com/Haidy777/node-youtubeAPI-simplifier從Bounty Killers的播放列表中獲取一些信息。順便說一下,這個庫設置似乎使用藍鳥的Promise(https://github.com/petkaantonov/bluebird),我不太瞭解。仰望初學者指南藍鳥給http://bluebirdjs.com/docs/beginners-guide.html字面上只是顯示將數據推送到承諾之外的數組

這篇文章是部分或完全未完成。歡迎您創建拉取請求來幫助完成這篇文章。

我能夠建立圖書館

var ytapi = require('node-youtubeapi-simplifier'); 
ytapi.setup('My Server Key'); 

除了列表關於賞金殺手的一些信息

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數組,並且我不確定最後的空數組是否由於作用域或某種不同步導致console.log(ytdata)在API調用完成之前被調用。

我將如何將每個賞金殺手視頻放入ytdata陣列中以便在全球範圍內銷售?

回答

2

的console.log(ytdata)API調用完成

在現貨之前被調用,這也正是這裏發生了什麼, 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 +,應該工作。

+0

值得一提的是我們的朋友,這是EcmaScript 6代碼:) – danday74

+0

@ danday74你是對的,我加了一個註釋:) – Shanoor

+0

是的,我是5+我現在要試試這個,因爲它接近這個想法我記得我只是不知道這個Promise是如何工作的 – phwd

1

console.log(ytdata)應該在FOR循環後立即生效。這些數據在解決承諾並且FOR循環執行完成並嘗試訪問它之前不會提供,直到您將獲得一個空數組。

(您的當前console.log不起作用,因爲該代碼在解決承諾前立即執行)。只有解決了承諾後,才執行THEN塊內的代碼。

如果您需要NOW或ASAP提供的數據,並且視頻請求需要很長時間,那麼您是否可以一次或按需或在單獨的線程上請求1個視頻(也許使用webworker)?你能實施緩存嗎?

可以使請求在背後前面的用戶之前甚至訪問該網頁? (不知道這是一個好主意,但它是一個想法)

您可以使用視頻縮略圖(如YouTube一樣),這樣點擊縮略圖,然後當你開始流媒體和播放視頻?

一些想法......希望這有助於

+0

好吧,你是說沒有辦法等待這個數據,所以我可以在所有的數據完成後得到它? 它不需要超長,但也不是那麼短。也符合你的意見,我可以減少請求1視頻,但這是假設請求將在'console.log(ytdata)'之前完成? 理想情況下,這個想法是在用戶甚至碰到頁面之前拉取這些數據,我猜想用另一種方式來完成這個任務就是用數據填充數據庫,從而完全跳過了youtube的配額。儘管如此,如果播放列表發生變化,它會變成手動的 – phwd

+0

我會在一個單獨的答案中重寫您的代碼,解釋它 - 一秒:) – danday74

+0

關於存儲數據(例如緩存),您可以每10分鐘發一個新請求到YTAPI檢查沒有任何變化。我期望YTVP請求getVideosForPlaylist比請求getDetailsForVideoIds快得多 - 只需要第一個請求來檢查更改 – danday74

1
ytdata = []; 

ytapi.playlistFunctions.getVideosForPlaylist('PLCCB0BFBF2BB4AB1D') 
    .then(function (data) { 
     // THE CODE INSIDE THIS THEN BLOCK IS EXECUTED WHEN ALL THE VIDEO IDS HAVE BEEN RETRIEVED AND ARE AVAILABLE 
     // YOU COULD SAVE THESE TO A DATASTORE IF YOU WANT 

     for (var i = 0, len = data.length; i < len; i++) { 
      var videoIds = [data[i].videoId]; 
      ytapi.videoFunctions.getDetailsForVideoIds(videoIds) 
        .then(function (video) { 
         // THE CODE INSIDE THIS THEN BLOCK IS EXECUTED WHEN ALL THE DETAILS HAVE BEEN DOWNLOADED FOR ALL videoIds provided 
         // AGAIN YOU CAN DO WHATEVER YOU WANT WITH THESE DETAILS 
         // ALSO NOW THAT THE DATA IS AVAILABLE YOU MIGHT WANT TO HIDE THE LOADING ICON AND RENDER THE PAGE! AGAIN JUST AN IDEA, A DATA STORE WOULD PROVIDE FASTER ACCESS BUT YOU WOULD NEED TO UPDATE THE CACHE EVERY SO OFTEN 
         // ytdata.push(video); <- Push a Bounty Killer Video 
      }); 
      // THE DETAILS FOR ANOTHER VIDEO BECOMES AVAILABLE AFTER EACH ITERATION OF THE FOR LOOP 
      } 
      // ALL THE DATA IS AVAILABLE WHEN THE FOR LOOP HAS COMPLETED 
}); 

// This is executed immediately before YTAPI has responded. 
// console.log(ytdata); This gives [] 
+0

警告:我剛剛注意到...... ytdata.push(video); ...可能是一個視頻陣列,因爲你傳遞多個videoIds getDetailsForVideoIds(videoIds)..我期望在這種情況下的響應是一個數組而不是一個視頻......要小心,不要偶然地結束與陣列內的數組:) :)只是一個FYI – danday74

+0

噢好的注意。我一定會檢查一下。 – phwd