2016-04-01 186 views
0

我試圖找出一種方法來等待,直到第一個函數(relatedVids(...))完成執行,然後執行第二個函數(relatedVidsDetails())。代碼所做的只是簡單地通過來自youtube api的單個$.get(...)請求進行循環,然後遍歷每個檢索到的項目。如何在執行第二個函數之前等待第一個函數完成執行?

在調試器中測試這種方法的問題是,它會在第一個函數去(到$.get()沒有實際得到任何東西),然後跳過進入第二功能(再次,直到$.get())。然後,它將繼續執行第一個函數,直到它完成所有項目的檢索,然後當它進入第二個函數時,它將執行相同的操作,但出於某種神祕原因,videoIdChainStr將所有視頻ID保存在一個字符串中第一個函數從來沒有被檢索或正在執行,因爲我懷疑它已經執行了第二個函數的$.get(...),並且在它有值時從未再次進行過「第二次」操作。

因此,我的下一步是嘗試使用$.Deferred(),據說這有助於在執行第二個函數之前先解析第一個函數,以確保第二個函數的值能夠在第二個函數中使用而不會跳過任何東西。但我不知道我是否正確地做了這件事,因爲它仍然使用或不使用$.Deferred()

第一功能(relatedVids(...)):

var relatedVidsDefer = function relatedVids(videoId) 
{ 
var r = $.Deferred(); 

$.get(// get related videos related to videoId 
    "https://www.googleapis.com/youtube/v3/search", 
    { 
     part: 'snippet', 
     maxResults: vidResults, 
     relatedToVideoId: videoId, 
     order: 'relevance', 
     type: 'video', 
     key: 'XXXXXXXXXX' 
    }, 

    function(data) 
    { 
     debugger; 
     $.each(data.items, 
      function(i, item) 
      { 
       try 
       { 
        console.log(item); 
        var vidTitle = item.snippet.title; // video title 
        var vidThumbUrl = item.snippet.thumbnails.default.url; // video thumbnail url 
        var channelTitle = item.snippet.channelTitle; // channel of uploaded video 
        var extractVideoId = null; // var to extract video id string from vidThumbUrl 

        // check if vidThumbUrl is not null, empty string, or undefined 
        if(vidThumbUrl) 
        { 
         var split = vidThumbUrl.split("/"); // split string when '/' seen 
         extractVideoId = split[4]; // retrieve the fourth index on the fourth '/' 
        } 
        else console.error("vidThumbUrl is either undefined or null or empty string."); 
        // if video title is longer than 25 characters, insert the three-dotted ellipse 
        if(vidTitle.length > 25) 
        { 
         var strNewVidTitle = vidTitle.substr(0, 25) + "..."; 
         vidTitle = strNewVidTitle; 
        } 

        // check whether channelTitle is March of Dimes 
        if(channelTitle === "March of Dimes") 
        { 
         extractedVideoIdArr.push(extractVideoId); // add the extracted video id to the array 

         // check if extractedVideoIdArr is not empty 
         if(extractedVideoIdArr !== 'undefined' && extractedVideoIdArr.length > 0) 
         { 
          console.log("before join(): ", extractedVideoIdArr); 
          videoIdChainStr = extractedVideoIdArr.join(", "); // change from an array to a chain string of videoIds for the relatedVidsDetails() 
          console.log("after join(): ", videoIdChainStr); 
         } 

         var vidThumbnail = '<div class="video-thumbnail"><a class="thumb-link" href="single-video.html"><div class="video-overlay"><img src="imgs/video-play-button.png"/></div><img src="' + vidThumbUrl + '" alt="No Image Available." style="width:204px;height:128px"/></a><p><a class="thumb-link" href="single-video.html">' + vidTitle + '</a><br/></div>'; //+ convert_time(vidDuration) + '/Views: ' + viewCount + '</p></div>'; 

         // print results 
         $('.thumb-related').append(vidThumbnail); 
         $(item).show(); // show current video thumbnail item 
        } 
        else $(item).hide(); // hide current video thumbnail item 
       } 
       catch(err) 
       { 
        console.error(err.message); // log error but continue operation  
       } 
      } 
     ); 
    } 
); 
return r; 
}; 

二級功能(relatedVidsDetails(...)):

var relatedVidsDetailsDefer = function relatedVidsDetails() 
{ 
// change extractvideoid into a string by tostring() or join() for param to recognize 
console.log("initial: ", extractedVideoIdArr); 
$.get(
    "https://www.googleapis.com/youtube/v3/videos", 
    { 
     part: 'snippet, contentDetails, statistics', 
     id: videoIdChainStr, // chain string of video ids to be called upon in a single request 
     key: 'XXXXXXXXXX', 
    }, 

    function(data) 
    { 
     debugger; 
     $.each(data.items, 
      function(i, item) 
      { 
       try 
       { 
        console.log("relatedVidsDetails()", item); 
        console.log("extractedvideoidarr: ", extractedVideoIdArr[i]); 
        var _vidDuration = item.contentDetails.duration; 
        var _viewCount = item.statistics.viewCount; 
        console.log("id: " + extractedVideoIdArr[i] + " duration: " + _vidDuration); 
        console.log("id: " + extractedVideoIdArr[i] + " viewCount: " + _viewCount); 


       } 
       catch(err) 
       { 
        console.error(err.message); // log error but continue operation  
       } 
      } 
     ); 
    } 
); 
}; 

代碼被跳過時,第二功能已被第二次打入:

$.each(data.items, 
    function(i, item) 
    { 
     try 
     { 
      console.log("relatedVidsDetails()", item); 
      console.log("extractedvideoidarr: ", extractedVideoIdArr[i]); 
      var _vidDuration = item.contentDetails.duration; 
      var _viewCount = item.statistics.viewCount; 
      console.log("id: " + extractedVideoIdArr[i] + " duration: " + _vidDuration); 
      console.log("id: " + extractedVideoIdArr[i] + " viewCount: " + _viewCount); 
     } 
     catch(err) 
     { 
      console.error(err.message); // log error but continue operation  
     } 
    } 
); 

videoIdChainStr爲空時,由於第二個功能正在跳入代碼而被跳過,然後在第一個功能完成時跳過該代碼並準備好第二個使用的值。當它具有要執行的值時,我無法獲得此videoIdChainStr

回答

0

那麼答案的問題:「如何等待第一個函數執行完畢執行第二前」將是:

使用回撥或承諾。

例子:

 function firstMethod() { 
      // half of first method actions ... 
      secondMethod(function() { 
       // other half of first method actions 
      }); 
     } 

     function secondMethod(callBack) { 
      // Second method actions 
      setTimeout(function() { // The timeout is just a way to simulate the time that a response make us wait 
       callBack(); 
      }, 5000);    
     } 
+0

我將如何使用承諾在這種情況下? – TheAmazingKnight

相關問題