在单独的 SDK 中传递函数回调(例如 Facebook-SDK)

Passing function-callback in seperate SDKs (e.g. Facebook-SDK)

在上一个问题中,我描述了我对正确调试 JS 的困惑。

现在我需要一些帮助来处理特定用例。

我正在尝试开发一个能够使用 facebook-sdk 登录 facebook 的 ember 应用程序。因此我生成了一个组件,它将一个按钮放入 dom 并对点击做出反应。请看这个:

import Ember from 'ember';

export default Ember.Component.extend({

  actions: {
    loginintofb: function() {
      console.log("loginintofb");
      FB.login(this.checkLoginState);
    }
  },

  checkLoginState: function() {
    console.log("checkLoginState"); // --> output | component.js:15
    //statusChangeCallback(response) //--> is not defined | also sdk.js:95 (???)
    FB.getLoginStatus(function(response) {

      // ##### HERE Ive got problems! #####
      statusChangeCallback(response); // --> is not defined | sdk.js:95

    });
  },

  statusChangeCallback: function(response) {
    console.log('statusChangeCallback');
    console.log(response);
    if (response.status === 'connected') {
      ...
    } else if (response.status === 'not_authorized') {
      ...
    } else {
      ...
    }
  }


});

问题是注释行:我必须将函数调用作为回调处理程序传递给 facebook api。所以换句话说:我在 ember 组件上下文中 --> 去 facebook-api --> 想在组件中调用一个函数。

正如您可能已经提到的:浏览器告诉我,statusChangeCallback(response); 不是函数。所以浏览器调用该函数的地方(我猜是在 Facebook-SDK 中)超出了该函数的范围。

另外:当把调用 statusChangeCallback() 放在 console.log("checkLoginState"); 的正下方时(参见注释 --> 未定义 ),浏览器会提示 statusChangeCallback没有定义!奇怪的是:终端说,这些参考错误来自 sdk.js 但那条线 一个(console.log(...))来自 component.js。怎么可能?

我怎样才能摆脱它?谁能帮我解决这个基于 "scope" 的问题?

这里有 2 个不同的问题。

  1. 要引用 statusChangeCallback 你需要脱离对象。
  2. 回调中的上下文不同。

考虑一下:

checkLoginState: function() {
  // This will display undefined:
  console.log(statusChangeCallback);
  // this will display the function:
  console.log(this.statusChangeCallback);

  // This will work:
  FB.getLoginStatus(response => {
    this.statusChangeCallback(response);
  });
},

fat arrow from 表示内部作用域继承自父checkLoginState

不过,我们可以简化您要尝试做的事情。或者:

checkLoginState: function() {
  FB.getLoginStatus(this.statusChangeCallback);
}

或者如果您希望 statusChangeCallback 的上下文保留在组件上,请绑定它:

checkLoginState: function() {
  FB.getLoginStatus(this.statusChangeCallback.bind(this));
}

there's a bind proposal that'll simplify it to (don't use this until it's out of experimental babel 尚未确定的未来中:

checkLoginState: function() {
  FB.getLoginStatus(::this.statusChangeCallback);
}