【问题标题】:How to execute code after multiple $.get() requests using a deferred object?如何使用延迟对象在多个 $.get() 请求后执行代码?
【发布时间】:2016-09-01 17:34:03
【问题描述】:

在执行总结果之前,我无法先执行多个 $.get() 请求。我有一个获取所有 50 个视频(最大)的请求,然后执行第二个请求(使用相同的 $.get() 请求和与上一个请求不同的 pageToken)检索接下来的 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...");
                         });
                     });
                 }
            );
        }         
    );
});

【问题讨论】:

  • @taplar 这是否意味着我必须使用d2 var 创建另一个testGetPlaylists(..) 函数,并使用不同的pageToken 再次运行整个$.get()?请求之间唯一改变的是pageToken,仅此而已。出于性能原因,我想避免重复代码。有什么想法吗?
  • @taplar 不确定你的意思。您介意详细说明吗?
  • 很难知道从哪里开始。神秘的deferredFunc到底是什么?为什么对testGetPlaylists() 的某些调用与其签名不匹配?为什么testGetPlaylists() 不返回任何东西?当您应该使用$.get(...).then(...) 时,为什么还要使用$.get(..., function() {...})?我可能可以修复这段代码,其他许多人也可以,但是你会从认真学习(jQuery)承诺然后自己修复它中获得更多好处。

标签: jquery asynchronous youtube-api jquery-deferred .when


【解决方案1】:

我相信您的问题源于依赖单个延迟 d1。 Iirc,延迟仅解决/拒绝一次,因此您重用它的逻辑将成为问题的一部分。

我建议第一步将您的方法 testGetPlaylists(playlistId, pageToken) 更改为类似于 testGetPlaylists(playlistId, pageToken, aDeferred) 这样您就可以传递延迟并引用该参数而不是全局 d1。这将允许您创建多个延迟并为您的目的重用该方法。

我会详细说明。你想打两个电话,但你想让第二个等第一个。并且您使用自己的 deferred 而不是从 $.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
    });
});

类似的东西。

【讨论】:

  • 我在帖子中更新了代码。我在$.when(testGetPlaylists(deferredFunc)).done(function() 上说ReferenceError: deferredFunc is not defined 时出错。还尝试了$.when(deferredFunc).done(function(),当我在解决它之后和返回语句之前定义它时,得到了相同的引用错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多