如何判断JavaScript异步函数何时结束?

时间:2012-02-21 16:27:55

标签: javascript jquery facebook

当这个异步函数结束时,我试图通过一些标志来确定。

这就是我调用我的功能的方式:

// Calling the function in a loop
for (var i=0,l=myIds.length; i<l; ++i) {
    install(pageId, myIds[i], apps_num[''+myIds[i]], <?php echo $this->comid ?>, '<?php echo $this->site_url; ?>');
}

这是我的职责:

install: function(pageId, appId, app_num, com_id, siteurl) {
    FB.getLoginStatus(function(response) {
        // Checking if connected to Facebook
        if (response.status === 'connected') {
            var uid = response.authResponse.userID;
            console.log(response.authResponse);
            var userAccessToken = response.authResponse.accessToken;

            // Get page access token
            FB.api('/'+pageId+'?fields=access_token='+userAccessToken, function(response) {
                var pageAccessToken = response.access_token;

                // Get information if user got this application
                FB.api('/'+pageId+'/tabs/'+appId+'?access_token='+pageAccessToken,
                    function(data) {
                        if (data.data.length < 1) {
                            console.log("Not installed, Installing...");

                            // Install the application
                            var params = {};
                            params['app_id'] = appId;
                            FB.api('/'+pageId+'/tabs?access_token='+pageAccessToken, 'post', params, function(response) {
                                if (!response || response.error) {
                                    console.log("Error Installing!");
                                }
                                else {
                                    console.log("Installed :)");
                                }
                            });
                        }
                        else {
                            console.log("Already installed.");
                        }
                    });
                });
            }
            else
                if (response.status === 'not_authorized') {
                    console.log("the user is logged in to Facebook, but not connected to the app.");
                }
                else {
                    console.log("the user isn't even logged in to Facebook.");
                }
            });
        }

我该如何解决这个问题?我试图使用静态变量,但我无法在异步函数内调用它们。

3 个答案:

答案 0 :(得分:3)

通常的做法是让任何需要知道异步调用结果的代码将函数引用传递给调用,然后函数在完成时调用(“回调”)。

因此,在您的情况下,您需要向install函数添加回调参数:

install: function(pageId, appId, app_num, com_id, siteurl, callback)
//                                        here ------------^

...然后在适当时从您传入FB.getLoginStatus和/或FB.api的回调中调用它,例如像这样

install: function(pageId, appId, app_num, com_id, siteurl, callback) {
        FB.getLoginStatus(function(response) {
                       // checking if connected to facebook
              if (response.status === 'connected') {
                var uid = response.authResponse.userID;
                console.log(response.authResponse);
                var userAccessToken = response.authResponse.accessToken;

                // get page access token
                FB.api('/'+pageId+'?fields=access_token='+userAccessToken, function(response) {
                    var pageAccessToken = response.access_token;

                    // get information if user got this app
                    FB.api('/'+pageId+'/tabs/'+appId+'?access_token='+pageAccessToken,
                       function(data) {
                         if (data.data.length < 1) {
                             console.log("Not installed, Installing...");

                            // install the app
                             var params = {};
                             params['app_id'] = appId;
                             FB.api('/'+pageId+'/tabs?access_token='+pageAccessToken, 'post', params, function(response) {
                                 if (!response || response.error) {
                                    callback(false, "Error installing");
                                    console.log("Error Installing!");
                                 } else {
                                    callback(true, "Installed");
                                    console.log("Installed :)");

                                 }
                                });
                         }
                         else {
                             callback(false, "Already installed.");
                             console.log("Already installed.");
                         }
                     });
                });
              } else if (response.status === 'not_authorized') {
                callback(false, "Logged in but not connected.");
                console.log("the user is logged in to Facebook, but not connected to the app.");
              } else {
                callback(false, "Not logged in.");
                console.log("the user isn't even logged in to Facebook.");
              }
             });
      }

我给了回调函数两个参数:一个布尔表示安装是否已执行,以及状态消息。

答案 1 :(得分:1)

首先,为函数添加一个额外的参数,它将接收一个函数对象

install:function(pageId,appId,app_num,com_id,siteurl,callbackFunction){

然后,在函数install之后,

之后
console.log("Installed :)");

你添加

callbackFunction();

这样,当您调用install函数时:

for (var i=0,l=myIds.length; i<l; ++i) {
    install(pageId, myIds[i], apps_num[''+myIds[i]], <?php echo $this->comid ?>, '<?php echo $this->site_url; ?>', function(){
        //do whatever you want;
    });
}

答案 2 :(得分:1)

jQuery通过让用户确定函数在函数完成时应该如何反应来完成它。这意味着,将函数作为参数。这称为回调

function install(pageId, appId, app_num, com_id, siteurl, pCallback) {
    //Doing cool stuff.
    //OK, I am finished.
    pCallback(a, b, c)
}

function lefinish(a, b, c) {
    alert(b);
}

// Calling install
install(pageId, appId, app_num, com_id, siteurl, lefinish)

作为一个额外的好处,如果你真的需要确切知道发生了什么,你可以在其中放入多个功能,具体取决于你的第一个功能的成功

function install(pageId, appId, app_num, com_id, siteurl, pCallback) {
    //Doing awesome stuff
    if (response.status === 'connected') {
        if (typeof(pCallback.onConnect) == 'function') {
           pCallback.onConnect(a,b,c);
        }
    }
    else
        if (response.status === 'not_authorized') {
            if (typeof(pCallback.onNoAuth) == 'function') {
                pCallback.onNoAuth(a,b,c);
            }
        }
        else {
            if (typeof(pCallback.onNotLoggedIn) == 'function') {
                pCallback.onNotLoggedIn(a,b,c);
            }
        }
}

function lefinish(a, b, c) {
   alert(b);
}

// Calling install
install(pageId, appId, app_num, com_id, siteurl, {
    'onConnect': function(a,b,c) {}, //Anonymous function
    'onNoAuth': lefinish //A predefined function
    // does not produce an error if onNotLoggedIn is not defined because of typeof().
})