Как выполнить код после нескольких запросов $.get() с использованием отложенного объекта?
У меня проблемы с выполнением нескольких $.get()
сначала запрашивает перед выполнением итоговых результатов. У меня есть запрос, который получает все 50 видео (макс.), А затем выполняет второй запрос (используя тот же $.get()
запрос с другой страницей, взятой из предыдущего запроса), которая получает следующие 50 видео. Теперь проблема заключается в том, что второй запрос завершен. Я пытаюсь распечатать результаты, хранящиеся в массиве общих значений по обоим запросам после того, как второй был выполнен, но я ударил стену.
Проблема:
// when first request is resolved, do a second request
$.when(testGetPlaylists(deferredFunc)).done(function()
{
testGetPlaylists(playlistId, globalPageToken, deferredFunc); // run second request...WORKS FINE
// doesn't work as it gets the same promise resolved from the first request and executes this function too
$.when(testGetPlaylists(deferredFunc)).done(function()
{
console.log("second request has completed! Logging total values from both requests...");
});
});
Также попробовал: (но получил ошибку: TypeError: testGetPlaylists(...) function is not defined
)
// when first request is resolved, do a second request
$.when(testGetPlaylists(deferredFunc)).done(function()
{
testGetPlaylists(playlistId, globalPageToken, deferredFunc).done(function()
{
console.log("second request has completed! Logging total values from both requests...");
});
});
JQuery:
// func to retrieve each video information
function testGetPlaylists(playlistId, pageToken, deferredFunc)
{
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",
{
part: 'snippet',
maxResults: vidResults
playlistId: playlistId,
pageToken: pageToken,
key: 'XXXXXXXXXXXXX'
},
// print the results
function(data)
{
$.each(data.items,
function(i, item)
{
console.log(item);
var vidTitle = item.snippet.title; // video title
var vidDesc = item.snippet.description; // video description
var videoId = item.snippet.resourceId.videoId; // video id
var vidThumbUrl = item.snippet.thumbnails.medium.url; // video thumbnail url
globalPlaylistId = playlistId;
globalPageToken = pageToken;
// code that gets all the video info stored into an array ...
}
);
// keep track of page token position
prevPageToken = data.prevPageToken;
nextPageToken = data.nextPageToken;
globalPageToken = nextPageToken;
}
).done(function() // execute after initial request is complete
{
d1.resolve(); // resolve when get request is successful
deferredFunc = d1; // pass to parameter
return d1.promise(); // return done
}).fail(function()
{
d1.reject(); //reject if get request fails
console.log("Could not fetch the videos.");
});
});
}
Документ готов:
$(document).ready(function()
{
$.get( // get channel name and load data
"https://www.googleapis.com/youtube/v3/channels",
{
part: 'contentDetails',
forUsername: channelName,
key: 'XXXXXXXXXX'
},
function(data)
{
$.each(data.items,
function(i, item)
{
console.log(item); // log all items to console
var playlistId = item.contentDetails.relatedPlaylists.uploads;
testGetPlaylists(playlistId); // initial loading playlist
// when first request is resolved, do a second request
$.when(testGetPlaylists(deferredFunc)).done(function()
{
testGetPlaylists(playlistId, globalPageToken, deferredFunc); // run second request
$.when(testGetPlaylists(deferredFunc)).done(function()
{
console.log("second request has completed! Logging total values from both requests...");
});
});
}
);
}
);
});
1 ответ
Я полагаю, что ваша проблема заключается в том, что вы полагаетесь на одну отсрочку, d1
, Iirc, deferreds разрешается / отклоняется только один раз, поэтому ваша логика повторного использования будет частью проблемы.
Я бы предложил в качестве первого шага изменить ваш метод testGetPlaylists(playlistId, pageToken)
быть чем-то вроде testGetPlaylists(playlistId, pageToken, aDeferred)
так что вы можете передать отложенный в и ссылаться на этот параметр вместо глобального d1
, Это позволит вам создать несколько отсрочек и повторно использовать этот метод для ваших целей.
Я уточню еще немного. Вы хотите сделать два звонка, но хотите, чтобы второй ожидал первого. И вы используете свою собственную отложенную, а не ту, которая была возвращена из $.ajax(), так как вы что-то делаете в своей работе. Так что логически шаги были бы что-то вроде...
var firstRequestDeferred = $.Deferred();
testGetPlaylists(playlistId, globalPageToken, firstRequestDeferred);
$.when(firstRequestDeferred).then(function() {
console.log('First request finished');
var secondRequestDeferred = $.Deferred();
testGetPlaylists(playlistId, globalPageToken, secondRequestDeferred);
$.when(secondRequestDeferred).then(function() {
console.log("Second request finished");
//do other stuff
});
});
Что-то вроде того.