如何检测Facebook的FB.init何时完成

2022-08-30 05:06:28

旧的JS SDK有一个名为FB.ensureInit的函数。新的SDK似乎没有这样的功能...如何确保在完全启动 API 调用之前不进行 API 调用?

我在每个页面的顶部都包含这个:

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();
  };

  (function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
  }());
</script>

答案 1

更新 Jan 04, 2012

似乎你不能像以前那样在之后直接调用依赖于FB的方法(例如),就像现在似乎是异步的一样。将代码包装到响应中似乎可以执行检测 API 何时完全准备就绪的技巧:FB.getAuthResponse()FB.init()FB.init()FB.getLoginStatus()

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        runFbInitCriticalCode(); 
    });

};  

或者如果使用下面的实现:fbEnsureInit()

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        fbApiInit = true;
    });

};  

原文:

如果你想在初始化FB时只运行一些脚本,你可以在里面放一些回调函数:fbAsyncInit

  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();

    runFbInitCriticalCode(); //function that contains FB init critical code
  };

如果你想精确替换FB.ensureInit,那么你将不得不自己写一些东西,因为没有官方的替代品(大错误imo)。这是我使用的:

  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();

    fbApiInit = true; //init flag
  };

  function fbEnsureInit(callback) {
        if(!window.fbApiInit) {
            setTimeout(function() {fbEnsureInit(callback);}, 50);
        } else {
            if(callback) {
                callback();
            }
        }
    }

用法:

fbEnsureInit(function() {
    console.log("this will be run once FB is initialized");
});

答案 2

实际上,Facebook已经提供了一种订阅身份验证事件的机制。

在你的情况下,你使用的是“status: true”,这意味着FB对象将请求Facebook提供用户的登录状态。

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});

通过调用“FB.getLoginStatus()”,您将再次运行相同的请求。

相反,您可以使用FB。Event.subscribe 以订阅 auth.statusChangeauth.authResponse在调用 FB.init 之前更改事件

FB.Event.subscribe('auth.statusChange', function(response) {
    if(response.status == 'connected') {
        runFbInitCriticalCode();
    }
});

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});

最有可能的是,当使用“status:false”时,您可以在FB.init之后立即运行任何代码,因为不会有异步调用。