我試圖找出一種方法來等待,直到第一個函數(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
。
我將如何使用承諾在這種情況下? – TheAmazingKnight