Javascript 如何在执行第二个函数之前等待第一个函数完成执行?
我试图找出一种方法,等待第一个函数(Javascript 如何在执行第二个函数之前等待第一个函数完成执行?,javascript,jquery,function,youtube-api,jquery-deferred,Javascript,Jquery,Function,Youtube Api,Jquery Deferred,我试图找出一种方法,等待第一个函数(relatedVids(…))完成执行,然后依次执行第二个函数(relatedVidsDetails())。代码所做的只是循环一个$。从youtube api获取(…)请求,并循环检索到的每个项目 在调试器中测试的问题是,它将进入第一个函数(直到$.get(),而实际上还没有得到任何东西),然后跳到第二个函数(再次,直到$.get())。然后,它将继续执行第一个函数,直到检索完所有项目,然后当它进入第二个函数时,它将执行相同的操作,但出于某种神秘的原因,将第一
relatedVids(…)
)完成执行,然后依次执行第二个函数(relatedVidsDetails()
)。代码所做的只是循环一个$。从youtube api获取(…)
请求,并循环检索到的每个项目
在调试器中测试的问题是,它将进入第一个函数(直到$.get()
,而实际上还没有得到任何东西),然后跳到第二个函数(再次,直到$.get()
)。然后,它将继续执行第一个函数,直到检索完所有项目,然后当它进入第二个函数时,它将执行相同的操作,但出于某种神秘的原因,将第一个函数中的所有视频ID保存在一个字符串中的videoIdChainStr
从未被检索或执行,因为我怀疑它已经执行了第二个函数的$。get(…)
,当它有值时,再也没有“第二次”执行它
因此,我的下一步是尝试使用$.Deferred()
,据说这有助于在执行第二个函数之前首先解析第一个函数,因此它将保证在第二个函数中使用第一个函数的值,而不会跳过任何内容。但是我不确定我是否做对了,因为它仍然使用或不使用$.Deferred()
做同样的事情
第一个函数(相关视频(…):
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;
};
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
}
}
);
第二次使用第二个函数时跳过的代码:
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;
};
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
。问题的答案是:“如何等待第一个函数完成执行,然后再执行第二个函数”:
使用回调或承诺
例如:
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);
}
在这种情况下,我将如何使用承诺?