javascript 如何在回调函数之外使用 FB.api(JS SDK) 响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7652558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use an FB.api(JS SDK) response outside of the callback function?
提问by Joshua
I am not having any issues with logging in or even calling the api, I just have an issue with getting the response outside of the api callback. I know that it runs asynchronously so I would like to put it in a function that would return the response. Here is my idea
我在登录甚至调用 api 时都没有任何问题,我只是在获取 api 回调之外的响应时遇到了问题。我知道它是异步运行的,所以我想把它放在一个可以返回响应的函数中。这是我的想法
//What I would like to be able to do
function fbUser(){
FB.api('/me', function(response){
//this logs the correct object
console.log(response);
});
//How do I get the response out here?
return response;
}
I would like to call the /me api function once in the beginning and then pass it around to my view objects (I just use the response inside of Backbone Views) and depending on what is needed make other api calls. I currently have certain things working by calling the view from inside of the callback
我想在开始时调用一次 /me api 函数,然后将它传递给我的视图对象(我只使用 Backbone 视图内部的响应),并根据需要进行其他 api 调用。我目前通过从回调内部调用视图来执行某些操作
//What I am doing now, but I lose the ability to pass anything other than the
//the current response to this function/View
FB.api('/me', function(response){
var newView = new facebookView({model: response});
});
I orginally was trying this, but because the api call is asynchronous I had issues with things being undefined
我最初是在尝试这个,但是因为 api 调用是异步的,所以我遇到了未定义的问题
//What I started with but had async issues
var fbResponse;
FB.api('/me', function(response){
fbResponse = response;
});
//I would then try and use fbResponse but it would be undefined
I lose the first response when I make the second. For example my first api call is to /me to get the user info. I can then call /your-fb-id/photos and get photos, but if I make the call to another function inside of the photo api callback I only can reference that response I lost the original /me response. If I could get the response out of the callback then I would be able to pass it as needed. I understand that response is only valid inside of the callback, so how do I make it valid outside of the callback while taking into account it's asynchronousness?
当我做第二个时,我失去了第一个响应。例如,我的第一个 api 调用是 /me 以获取用户信息。然后我可以调用 /your-fb-id/photos 并获取照片,但是如果我调用 photo api 回调中的另一个函数,我只能引用该响应我丢失了原始的 /me 响应。如果我可以从回调中获得响应,那么我将能够根据需要传递它。我知道响应仅在回调内部有效,那么在考虑到它的异步性的同时,如何使其在回调外部有效?
回答by Joshua
OK everyone I figured this out. It took me a long time and reading many different pages. What I said I wanted to do all deals with callbacks and closures. I will first cover the callback issue. Because the FB.api function is asynchronous you never know when it will return. You can stop Javascript or set a timer, but that is a horrible way to do this. You need a callback. In fact the FB.api is using a callback. That's what the anonymous function as the second parameter is. What I did was create another function that called fbUser and used a callback. Here is what I did:
好的,我想通了。我花了很长时间阅读许多不同的页面。我所说的我想做所有与回调和闭包有关的交易。我将首先介绍回调问题。因为 FB.api 函数是异步的,所以你永远不知道它什么时候会返回。您可以停止 Javascript 或设置计时器,但这是一种可怕的方式。你需要回调。事实上,FB.api 正在使用回调。这就是作为第二个参数的匿名函数。我所做的是创建另一个调用 fbUser 并使用回调的函数。这是我所做的:
function startThis() {
var getUser = fbUser(function(model){
console.log(model);
startapp(model);
});
};
function fbUser(callback){
FB.api('/me', function(response){
callback(response);
});
}
The startThis function is called on a positive Facebook auth response. It then calls the fbUser function which has a callback. The callback returns the callback from the FB.api function. Because startThis uses that callback with the return value being called model, the other code will not execute until the callback returns. No more undefined issues. These functions are just wrappers to get the Facebook response to my views. I may have added one too many layers of abstraction, but if you want to pass around the response this is the way.
在正面的 Facebook 身份验证响应中调用 startThis 函数。然后它调用具有回调的 fbUser 函数。回调从 FB.api 函数返回回调。因为 startThis 使用该回调,返回值被称为模型,其他代码在回调返回之前不会执行。没有更多未定义的问题。这些函数只是让 Facebook 响应我的观点的包装器。我可能添加了太多抽象层,但是如果您想传递响应,这就是方法。
Secondly I wanted to pass this response on to another view. For example one view loads basic info (using the response from fbUser). I now want to pass that to another view that loads photos (I know this is not best practices MVC, but by using Facebook I don't have much control over the Model). The problem I had though was I couldn't pass the original response to the next view because inside of the callback function for the FB.api call this
refers to the Window
and not the object I was in. Solution: closures. I won't explain this perfectly, but a closure is a local variable inside of a function that still has a reference inside of an anonymous function. Here is my solution which should illustrate what I am talking about:
其次,我想将此响应传递给另一个视图。例如,一个视图加载基本信息(使用来自 fbUser 的响应)。我现在想将它传递给另一个加载照片的视图(我知道这不是 MVC 的最佳实践,但是通过使用 Facebook,我对模型没有太多控制权)。但我遇到的问题是我无法将原始响应传递给下一个视图,因为 FB.api 调用的回调函数内部this
引用Window
了我所在的对象而不是我所在的对象。解决方案:闭包。我不会完美地解释这一点,但闭包是函数内部的局部变量,在匿名函数内部仍然具有引用。这是我的解决方案,它应该说明我在说什么:
photos: function(){
var This = this;
var apiString = '/' + this.model.id + '/photos';
FB.api(apiString, function(response){
loadPhoto(response, 1, This.model);
});
The function loadPhoto is a wrapper to load a photo view (I know backbone can help me with loading different views, but I was tackling one problem at a time). It takes the photo api call as the model, a number as an offset, and the origanl response. The first line in this function sets this to a local variable This. That allows me inside of the anonymous callback function to reference the object this was called from.
函数 loadPhoto 是加载照片视图的包装器(我知道主干可以帮助我加载不同的视图,但我一次解决一个问题)。它将照片 api 调用作为模型,一个数字作为偏移量,以及原始响应。此函数的第一行将 this 设置为局部变量 This。这允许我在匿名回调函数内部引用调用它的对象。
I hope this can help someone as I spent a lot of hours and a lot of testing time to find the solution to this. If you don't know about how callbacks or closures work it is hard to find the information you are looking for.
我希望这可以帮助某人,因为我花了很多时间和大量测试时间来找到解决方案。如果您不知道回调或闭包的工作原理,则很难找到您要查找的信息。