15

Non ho alcun problema con il login o anche chiamando l'API, ho solo un problema con ottenere la risposta al di fuori del callback API. So che funziona in modo asincrono quindi vorrei metterlo in una funzione che restituirebbe la risposta. Qui è la mia ideaCome utilizzare una risposta FB.api (JS SDK) al di fuori della funzione di callback?

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

vorrei chiamare la me funzione/api una volta all'inizio e poi passarlo intorno ai miei oggetti vista (mi basta usare la risposta all'interno di Backbone Viste) ea seconda di ciò che è necessario effettuare altre chiamate API. Io attualmente ho alcune cose di lavoro chiamando la vista dall'interno della richiamata

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

ho originariamente stava cercando questo, ma perché la chiamata API è asincrona ho avuto problemi con le cose che sono undefined

//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 perdere la prima risposta quando faccio il secondo. Ad esempio la mia prima chiamata api è a/me per ottenere le informazioni dell'utente. Posso quindi chiamare/your-fb-id/foto e ottenere foto, ma se effettuo la chiamata a un'altra funzione all'interno della foto a callback di API, posso solo fare riferimento a tale risposta. Ho perso la risposta originale/me. Se potessi ottenere la risposta dal callback, sarei in grado di passarla se necessario. Comprendo che la risposta è valida solo all'interno del callback, quindi come faccio a renderlo valido al di fuori della callback tenendo conto che è asincrona?

risposta

24

OK tutti quelli che ho capito. Mi ci è voluto molto tempo e ho letto molte pagine diverse. Quello che ho detto che volevo fare tutte le operazioni con i callback e le chiusure. In primo luogo coprirò il problema del callback. Perché la funzione FB.api è asincrona non si sa mai quando tornerà. È possibile interrompere Javascript o impostare un timer, ma questo è un modo orribile per farlo. Hai bisogno di una richiamata. In effetti FB.api sta usando una callback. Questo è ciò che è la funzione anonima come secondo parametro. Quello che ho fatto è stato creare un'altra funzione chiamata fbUser e utilizzata una richiamata. Ecco cosa ho fatto:

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

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

La funzione startThis viene chiamata su una risposta di autenticazione Facebook positiva. Quindi chiama la funzione fbUser che ha un callback. Il callback restituisce il callback dalla funzione FB.api. Poiché start utilizza questa richiamata con il valore restituito chiamato modello, l'altro codice non verrà eseguito fino a quando non viene restituito il callback. Niente più problemi non definiti. Queste funzioni sono solo wrapper per ottenere la risposta di Facebook alle mie opinioni. Potrei aver aggiunto uno o più strati di astrazione, ma se vuoi far passare la risposta, questa è la via.

In secondo luogo, volevo passare questa risposta a un'altra vista. Ad esempio una vista carica le informazioni di base (usando la risposta di fbUser). Ora voglio passare a un'altra vista che carica le foto (so che questo non è il miglior metodo MVC, ma usando Facebook non ho molto controllo sul modello). Il problema che avevo era che non potevo passare la risposta originale alla vista successiva perché all'interno della funzione di callback per la chiamata FB.api this si riferisce allo Window e non all'oggetto in cui mi trovavo. Soluzione: chiusure. Non lo spiegherò perfettamente, ma una chiusura è una variabile locale all'interno di una funzione che ha ancora un riferimento all'interno di una funzione anonima. Qui è la mia soluzione, che dovrebbe illustrare ciò di cui sto parlando:

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

La loadPhoto funzione è un wrapper per caricare una vista fotografico (lo so spina dorsale mi può aiutare con il caricamento di diversi punti di vista, ma mi è stato affrontare un problema alla un tempo). Prende la chiamata a foto come modello, un numero come offset e la risposta originale. La prima riga in questa funzione lo imposta su una variabile locale.Ciò mi consente di entrare nella funzione di callback anonimo per fare riferimento all'oggetto da cui è stato chiamato.

Spero che questo possa aiutare qualcuno come ho passato un sacco di ore e un sacco di tempo di test per trovare la soluzione a questo. Se non sai come funzionano i callback o le chiusure, è difficile trovare le informazioni che stai cercando.

+0

Grazie! Mi ha aiutato esattamente nella stessa situazione! –

Problemi correlati