Я пытаюсь найти способ подождать до первой функции (relatedVids(...)
), чтобы закончить выполнение, а затем, в свою очередь, выполнить вторую функцию (relatedVidsDetails()
). То, что делает код, - это просто цикл через один запрос $.get(...)
от apt youtube и цикл через каждый полученный элемент.Как дождаться завершения первой функции до выполнения второго?
Проблема с этим, как проверено в отладчике, заключается в том, что он будет работать в первой функции (вплоть до $.get()
, не получив ничего еще), затем перейдите во вторую функцию (еще раз, до $.get()
). Затем он перейдет к выполнению первой функции до тех пор, пока она не закончит извлечение всех элементов, а затем, когда она войдет во вторую функцию, она сделает то же самое, но по какой-то загадочной причине, videoIdChainStr
, которая содержит все идентификаторы видео в строке из первая функция никогда не извлекается или не выполняется, так как я подозревал, что она уже выполнила вторую функцию $.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