Jak korzystać z FB.odpowiedź api (JS SDK) poza funkcją callback?

Nie mam żadnych problemów z zalogowaniem się lub nawet wywołaniem api, po prostu mam problem z uzyskaniem odpowiedzi poza wywołaniem zwrotnym api. Wiem, że działa asynchronicznie, więc chciałbym umieścić go w funkcji, która zwróci odpowiedź. Oto mój pomysł

//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;
}

Chciałbym wywołać funkcję /me api raz na początku, a następnie przekazać ją do moich obiektów widoku (używam tylko odpowiedzi wewnątrz widoków szkieletowych) i w zależności od tego, co jest potrzebne, stworzyć inne api telefony. Obecnie niektóre rzeczy działają, wywołując widok z wnętrza wywołania zwrotnego

//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});
   });

Początkowo próbowałem tego, ale ponieważ wywołanie api jest asynchroniczne, miałem problemy z tym, że rzeczy są niezdefiniowane

//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
Tracę pierwszą odpowiedź, gdy wykonuję drugą. Na przykład moje pierwsze wywołanie api to / me, aby uzyskać informacje o użytkowniku. Następnie mogę zadzwonić / your-FB-id / photos I uzyskać zdjęcia, ale jeśli wykonam połączenie do innej funkcji wewnątrz Photo API callback mogę tylko odniesienie do tej odpowiedzi straciłem oryginalną / moją odpowiedź. Gdybym mógł uzyskać odpowiedź z połączenia zwrotnego, byłbym w stanie przekazać go w razie potrzeby. Rozumiem, że odpowiedź jest ważna tylko wewnątrz callback, więc jak zrobić to ważne poza callback biorąc pod uwagę to asynchroniczność?
Author: Joshua, 2011-10-04

1 answers

/ Align = "left" / Zajęło mi to dużo czasu i czytanie wielu różnych stron. To, co powiedziałem, chciałem zrobić wszystkie umowy z odwołaniami i zamknięciami. Najpierw omówię kwestię oddzwaniania. Bo FB.funkcja api jest asynchroniczna nigdy nie wiadomo, kiedy powróci. Możesz zatrzymać Javascript lub ustawić timer, ale jest to okropny sposób na to. Potrzebujesz oddzwonienia. W rzeczywistości FB.api używa połączenia zwrotnego. Tym właśnie jest funkcja anonimowa jako drugi parametr. To co zrobiłem było Utwórz inną funkcję, która wywołała fbUser i użyła wywołania zwrotnego. Oto co zrobiłem:

function startThis() {  
    var getUser = fbUser(function(model){
        console.log(model);
        startapp(model);
    }); 
};

function fbUser(callback){  
        FB.api('/me', function(response){
                callback(response);
            });
}

Funkcja startThis jest wywoływana po pozytywnej odpowiedzi Facebook auth. Następnie wywołuje funkcję fbUser, która ma wywołanie zwrotne. Callback zwraca callback z FB.funkcja api. Ponieważ startThis używa tego wywołania zwrotnego z wartością zwracaną jako model, drugi kod nie zostanie wykonany, dopóki wywołanie zwrotne nie powróci. Koniec z nieokreślonymi kwestiami. Te funkcje są tylko owijkami, aby uzyskać Odpowiedź Facebook na moje poglądy. Może dodałem o jedną warstwę abstrakcji za dużo, ale jeśli chcesz przekazać odpowiedź to jest sposób.

Po Drugie chciałem przekazać tę odpowiedź innemu poglądowi. Na przykład jeden widok wczytuje podstawowe informacje (przy pomocy odpowiedzi fbusera). Teraz chcę przekazać to do innego widoku, który ładuje zdjęcia(wiem, że nie jest to najlepsze praktyki MVC, ale używając Facebook nie mam dużej kontroli nad modelem). Problemem, który miałem, było to, że nie mogłem przejść oryginalna odpowiedź na następny Widok, ponieważ wewnątrz funkcji zwrotnej dla FB.wywołanie api this odnosi się do Window, a nie do obiektu, w którym byłem. Rozwiązanie: zamknięcia. Nie wyjaśnię tego doskonale, ale zamknięcie jest zmienną lokalną wewnątrz funkcji, która nadal ma odniesienie wewnątrz funkcji anonimowej. Oto moje rozwiązanie, które powinno zilustrować to, o czym mówię:

photos: function(){
            var This = this;
            var apiString = '/' + this.model.id + '/photos';
            FB.api(apiString, function(response){
                loadPhoto(response,  1, This.model);
            });

Funkcja loadPhoto jest opakowaniem do wczytania widoku zdjęć (wiem, że może mi pomóc w Ładowanie różnych widoków, ale rozwiązywałem jeden problem na raz). Bierze wywołanie photo api jako model, numer jako offset i odpowiedź origanl. Pierwsza linia w tej funkcji ustawia this na zmienną lokalną This. To pozwala mi wewnątrz anonimowej funkcji zwrotnej odwoływać się do obiektu, z którego został wywołany.

Mam nadzieję, że to może komuś pomóc, ponieważ spędziłem wiele godzin i dużo czasu na testowaniu, aby znaleźć rozwiązanie tego problemu. Jeśli nie wiesz o tym, jak callbacks lub zamknięcie pracy trudno jest znaleźć informacje, których szukasz.

 24
Author: Joshua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 14:32:55