Attendre l'execution de l'API Facebook avant de traiter son retour

Par SacreOl, il y a 11 ans


Bonjour,
Tout d'abord voici mon code :

jQuery(document).ready(function($) { // Gestion de la récupération des albums Facebook $('.facebookUpload').click(function(event) { event.preventDefault(); // console.log(albums.constructor); var albums = new Array(); while (albums.length == 0) { albums = getAlbums(); } console.log(albums); // showAlbums(); }); }); function getAlbums () { // Make an API call to get the facebook albums de l'utilisateur connecté FB.api( "/me/albums", function (response) { var albums = new Array(); // Si on trouve des albums if (response && !response.error) { // déclaration des variables var data = response.data; // console.log(data); // Construction du tableau Albums for (var i = 0; i < data.length; i++) { albums[i] = {"cover_photo" : data[i]['cover_photo'], 'name' : data[i]['name'], 'count' : data[i]['count']}; }; return albums; // console.log(albums); } } ); }

Actuellement la fonction getAlbums() me retourne toujours un tableau vide. J'ai compris d'où venait le problème grâce aux breakpoints de CHROME. Il se trouve que l'API Facebook "met trop de temps" à répondre pour l'execution du javascript qui suit l'appel.
Du coup il faudrait que j'attende la réponse de API avant de continuer l'execution du code.
Ma requête est simple, quelqu'un connaît-il un moyen d'attendre proprement que mon tableau albums entièrement construit avant de le retourner, et de poursuivre le traitement.
PS : J'ai beaucoup d'autres appels à faire vers l'API de Facebook pour ce script, alors j'ai besoin qu'il soient clair et lisible.
C'est pourquoi je veux abosulement utiliser des fonctions pour gagner en lisibilité.
Merci pour l'intérêt que vous venez d'accorder à mon sujet. ^^

5 réponses

nobodyisreal, il y a 11 ans

Salut, si tu souhaites attendre un retour complet de l'api fb, tu devrais je pense utiliser les promises.
Voici une simulation de latence http://pastebin.com/FLfNARcs

SacreOl, il y a 11 ans

Désolé, mais je ne comprends pas bien dans quoi piocher dans ce que tu m'as fourni.

SacreOl, il y a 11 ans

Voici mon code :

jQuery(document).ready(function($) { // Connexion avec facebook (demande d'autorisation) $('.facebookConnect').click(function(event) { event.preventDefault(); var url = $(this).attr('href'); FB.login(function (response) { if (response.authResponse) { window.location = url; } }, {scope : 'email, user_photos'}); }); // Gestion de la récupération des albums Facebook $('.facebookUpload').on('click', function() { event.preventDefault(); promise = getAlbums(); promise.then(function(res) { console.log('Retour API FB', res); console.log('Le traitement à effectuer'); }); }); }); function getAlbums () { // Make an API call to get the facebook albums de l'utilisateur connecté FB.api( "/me/albums", function (response) { var albums = new Array(); // Si on trouve des albums if (response && !response.error) { // déclaration des variables var data = response.data; // console.log(data); // Construction du tableau Albums for (var i = 0; i < data.length; i++) { albums[i] = {"cover_photo" : data[i]['cover_photo'], 'name' : data[i]['name'], 'count' : data[i]['count']}; }; return albums; } } ); }

Il renvoie une erreur de then()
Uncaught TypeError: Cannot read property 'then' of undefined

antho07, il y a 11 ans

Bonjour ,

le problème est que tu penses ton algo en synchrone alors que là ton traitement est asynchrone...

Sans changer ta structure :

jQuery(document).ready(function($) { // Gestion de la récupération des albums Facebook $('.facebookUpload').click(function(event) { event.preventDefault(); // console.log(albums.constructor); //On passe une callback en paramètre getAlbums(function(data){ console.log(data); showAlbums(); }); }); }); function getAlbums (callback) { // Make an API call to get the facebook albums de l'utilisateur connecté FB.api( "/me/albums", function (response) { var albums = new Array(); // Si on trouve des albums if (response && !response.error) { // déclaration des variables var data = response.data; // console.log(data); // Construction du tableau Albums for (var i = 0; i < data.length; i++) { albums[i] = {"cover_photo" : data[i]['cover_photo'], 'name' : data[i]['name'], 'count' : data[i]['count']}; }; //On execute la callback en lui passant l'objet récupéré: callback(albums); } } ); }
SacreOl, il y a 11 ans

J'ai trouvé en partie mon bonheur avec les "promises".
En jQuery :

deferred = jQuery.Deferred();

Pour ce que ça intéresse : L'objet Deferred en jQuery.