#jquery #ajax #json
#jquery #ajax #json
Вопрос:
Мне нужно сделать несколько вызовов API YouTube через AJAX для получения видеоинформации в формате JSON.
Каждый из вызовов может обрабатываться синхронно, но после получения всех данных его необходимо обработать отобразить.
Как я могу гарантировать, что функция обработки не вызывается до получения всех данных? Моим текущим решением было вызывать функцию AJAX повторно, но я чувствую, что есть гораздо лучшее решение.
Любая помощь была бы очень признательна.
var categoryWrapper,categories;
var catCnt=0;
function initialiseVideoLibrary() {
categories=new Array("health","hiv","education","volunteering");
getYouTubeData();
}
function getYouTubeData() {
ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" categories[catCnt] "?v=2amp;alt=jsoncamp;max-results=5amp;orderby=relevance";
$.ajax({
type: "GET",
url: ytJsonUrl,
cache: false,
dataType:'jsonp',
success: function(ytJsonResponse){
if (catCnt < categories.length) {
showCategory(categories[catCnt],ytJsonResponse);
getYouTubeData();
catCnt ;
} else {
tabVideos();
}
}
});
}
function showCategory(cat,ytResponse) {
categoryWrapper = $('<div></div>').addClass('category');
$(categoryWrapper).append($('<h3></h3>').text(cat));
contentDiv = $('<div></div>').addClass('content');
$.each(ytResponse.data.items,function(i,video) {
videoWrapper = $('<div></div>').addClass('video');
$(videoWrapper).append($('<p></p>').text(video.id));
$(videoWrapper).append($('<p></p>').text(video.title));
$(videoWrapper).append($('<img></img>').attr('src',video.thumbnail.sqDefault));
$(contentDiv).append(videoWrapper);
});
$(categoryWrapper).append(contentDiv);
$("#videolist").append(categoryWrapper);
}
function tabVideos() {
$("#videolist").tabulation({tabAlignment : "right", titleTag : "h3", tabPosition : "top"});
}
Ответ №1:
Это было бы отличным использованием jQuery.Deferred
.
Просто сохраните возвращаемые значения вызовов jQuery.ajax
, а затем передайте их jQuery.when
.
Редактировать: как я только что заметил, это не очевидно из документации, я подумал, что хотел бы отметить, что вы можете передать массив deferred
s when
, используя следующий синтаксис:
$.when.apply(null, ajaxReturnValueArray).then(function() {
tabVideos(); // Assuming this is the method you wanted to call
});
Ответ №2:
Я не уверен, но вы можете попробовать со следующим изменением :
function getYouTubeData() {
ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" categories[catCnt] "?v=2amp;alt=jsoncamp;max-results=5amp;orderby=relevance";
$.ajax({
type: "GET",
url: ytJsonUrl,
cache: false,
async: false,
dataType:'jsonp',
success: function(ytJsonResponse){
if (catCnt < categories.length) {
showCategory(categories[catCnt],ytJsonResponse);
getYouTubeData();
catCnt ;
} else {
tabVideos();
}
}
});
}
Ответ №3:
Проверьте .ajaxStop()
, что-то подобное может сработать (извините, непроверено!)
var categoryWrapper,categories;
function initialiseVideoLibrary() {
categories=new Array("health","hiv","education","volunteering");
getYouTubeData();
}
function getYouTubeData() {
$.each(categories, function(index, value) {
ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" value "?v=2amp;alt=jsoncamp;max-results=5amp;orderby=relevance";
$.ajax({
type: "GET",
url: ytJsonUrl,
cache: false,
dataType:'jsonp',
success: function(ytJsonResponse){
showCategory(value,ytJsonResponse);
}
});
});
}
function showCategory(cat,ytResponse) {
categoryWrapper = $('<div></div>').addClass('category');
$(categoryWrapper).append($('<h3></h3>').text(cat));
contentDiv = $('<div></div>').addClass('content');
$.each(ytResponse.data.items,function(i,video) {
videoWrapper = $('<div></div>').addClass('video');
$(videoWrapper).append($('<p></p>').text(video.id));
$(videoWrapper).append($('<p></p>').text(video.title));
$(videoWrapper).append($('<img></img>').attr('src',video.thumbnail.sqDefault));
$(contentDiv).append(videoWrapper);
});
$(categoryWrapper).append(contentDiv);
$("#videolist").append(categoryWrapper);
}
$("#videolist").ajaxStop(function() {
$(this).tabulation({tabAlignment : "right", titleTag : "h3", tabPosition : "top"});
});
Ответ №4:
Я думаю, что наиболее чистым способом было бы сделать вызов ajax синхронным, а затем вызвать getYouTubeData() последовательно в цикле for .
getYouTubeData() должен быть:
function getYouTubeData(cat) {
ytJsonUrl = "https://gdata.youtube.com/feeds/api/users/vsomediauk/uploads/-/" cat "?v=2amp;alt=jsoncamp;max-results=5amp;orderby=relevance";
$.ajax({
type: "GET",
url: ytJsonUrl,
cache: false,
async: false, //this is to make tha ajax call synchronous
dataType:'jsonp',
success: function(ytJsonResponse){
showCategory(cat,ytJsonResponse);
}
});
}
И вы могли бы вызвать его следующим образом:
for (var iC = 0; iC < categories.length; iC ){
getYouTubeData(categories[iC]);
}
tabVideos();
Таким образом, tabVideos() будет вызван после завершения всех вызовов getYouTubeData() .