0

我试图在学习C/C++之后教自己网站相关的东西,如JavaScript和API。这个项目应该是一个简单的网页,它使用Facebook JavaScript SDK来登录Facebook并显示个人资料中的信息。我已成功完成登录部分,但由于需要访问令牌,因此无法调用FB.api()函数。现在,我试图将访问令牌保存到名为token的变量,但它似乎没有工作。我使用三个console.log()进行调试,我发现最后/第三个调用返回undefined,因为由于某种原因,它似乎首先运行(根据Firefox中的F12 dev控制台)。到底是怎么回事?无法将访问令牌从FB.getLoginStatus()保存到var,因为函数未按顺序运行

main.js:

function main() 
{ 
    var token; 

    FB.getLoginStatus(function getLoginStatusCallback(response) 
    { 
     if (response.status === "connected") 
     { 
     document.getElementById("loginButton").style.display = "none"; 
     } 
     else 
     { 
     document.getElementById("loginButton").style.display = "all"; 
     } 
     //THIS OUTPUTS THE TOKEN SUCCESSFULLY 
     console.log(response.authResponse.accessToken); 
     //THIS WORKS 
     token = response.authResponse.accessToken; 
     //THIS OUTPUTS THE TOKEN SUCCESSFULLY 
     console.log(token); 
    }, true); 

    //THIS OUTPUTS UNDEFINED! 
    console.log("token = " + token); 

    Fb.api("/me", "get", token, function() { 
     //stuff here 
    }); 
} 

我如何初始化FB的JavaScript SDK和调用主(这样我就可以在其他地方使用FB对象)。

facebook.js:

window.fbAsyncInit = function() { 
    FB.init({ 
     appId: 'my app id here', 
     cookie: true, 
     xfbml: true, 
     version: 'v2.8' 
    }); 
    FB.AppEvents.logPageView(); 
    //CALLING MAIN HERE 
    main(); 
    }; 

    (function(d, s, id) { 
    var js, fjs = d.getElementsByTagName(s)[0]; 
    if (d.getElementById(id)) { 
     return; 
    } 
    js = d.createElement(s); 
    js.id = id; 
    js.src = "https://connect.facebook.net/en_US/sdk.js"; 
    fjs.parentNode.insertBefore(js, fjs); 
    }(document, 'script', 'facebook-jssdk')); 

在我的HTML文件头(第一个定义SDK初始化):

<head> 
    <meta charset="utf-8" /> 
    <title>Profile</title> 
    <link rel="stylesheet" href="style.css" /> 
    <script src="facebook.js"></script> 
    <script src="main.js"></script> 
</head> 

这里是从Firefox的开发者控制台(第三的console.log似乎为什么会发生这种情况?):

token = undefined main.js:23:4  <-- I think it should run last but it runs first 
TheTokenPrintsHere main.js:18:7 
TheTokenPrintsHere main.js:20:7 

我来自C/C++ if t帽子帮助,这是我第一次使用API​​和Web SDKs。谢谢!

回答

0

您正在观察的是JavaScript异步执行代码的结果。接收到FaceBook的响应(可能需要2秒,5秒或2分钟)后,function getLoginStatusCallback(response)块中的所有代码将被执行

JavaScript只有一个线程,所以语言设计者使得这个代码块只有在收到响应时才会执行。

如果你想迫使你的代码同步执行,你可以移动的最后2所陈述main()第一胎块中,像这样:

function main() 
{ 
    var token; 

    FB.getLoginStatus(function getLoginStatusCallback(response) 
    { 
     if (response.status === "connected") 
     { 
     document.getElementById("loginButton").style.display = "none"; 
     } 
     else 
     { 
     document.getElementById("loginButton").style.display = "all"; 
     } 
     token = response.authResponse.accessToken; 

     console.log("token = " + token); 

     Fb.api("/me", "get", token, function() { 
     // this will work now. 
     }); 

    }, true); 
} 
+0

我能做的来解决这个问题? – TomaszS

+0

@TomaszS还有其他解决方案。最常见的解决方法是使用[Promise](https://developers.google.com/web/fundamentals/getting-started/primers/promises) – matthewninja

+0

我将第三个console.log()和Fb.api ()在另一个函数中,并从FB.getLoginStatus()中调用它。它的工作原理,谢谢! – TomaszS