Как выполнить код после нескольких запросов $.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
    });
});

Что-то вроде того.

Другие вопросы по тегам