【问题标题】:How to wait for the first function to finish executing before the second is executed?如何在执行第二个函数之前等待第一个函数完成执行?
【发布时间】:2016-04-01 20:17:07
【问题描述】:

我试图找出一种方法,等待第一个函数 (relatedVids(...)) 完成执行,然后依次执行第二个函数 (relatedVidsDetails())。代码所做的只是循环遍历来自 youtube api 的单个 $.get(...) 请求,并遍历检索到的每个项目。

在调试器中测试的问题在于,它将进入第一个函数(直到 $.get() 还没有实际得到任何东西)然后跳到第二个函数(再次,直到 @987654325 @)。然后,它将继续执行第一个函数,直到完成检索所有项目,然后当它进入第二个函数时,它会做同样的事情,但出于某种神秘的原因,videoIdChainStr 将所有视频 ID 保存在一个第一个函数的字符串永远不会被检索或执行,因为我怀疑它已经执行了第二个函数的$.get(...),并且当它有值时再也没有“第二次”执行过。

所以,我的下一步是尝试使用$.Deferred(),据说这有助于在开始执行第二个函数之前先解决第一个函数,因此它将保证第一个函数的值在第二个函数中使用而不会跳过任何事物。但我不确定我是否做对了,因为无论是否使用$.Deferred(),它仍然会做同样的事情。

第一个函数(relatedVids(...)):

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;
};

第二个函数(relatedVidsDetails(...)):

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 具有要执行的值时,我无法得到它。

【问题讨论】:

    标签: javascript jquery function youtube-api jquery-deferred


    【解决方案1】:

    那么问题的答案:“如何在执行第二个函数之前等待第一个函数完成执行”将是:

    使用回调或承诺。

    例子:

            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);               
            }
    

    【讨论】:

    • 在这种情况下我将如何使用 Promise?
    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 2019-02-16
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    相关资源
    最近更新 更多