15

Oturum açmada veya api çağrısında herhangi bir sorun yaşıyorum, yalnızca yanıtı api geri çağırma dışında almakla ilgili bir sorun yaşıyorum. Eşzamansız olarak çalıştığını biliyorum, bu yüzden cevabı geri döndürecek bir işleve koymak istiyorum. Burada başlangıçta bir defa/me API işlevi çağırmak ve sonra benim bakış nesnelere dolaştır (Sadece Omurga Görüntüleme iç yanıtını kullanın) ve istiyorum benim fikrimGeri arama işlevinin dışında bir FB.api (JS SDK) yanıtını nasıl kullanırım?

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

olduğunu ne bağlı diğer api çağrılarını yapmak gerekiyordu. Şu anda bazı şeyler

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

Ben orginally bu çalışıyordum geri arama içinden görünümü çağırarak çalışan, ancak API çağrısı asenkron olduğu için işler

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

Ben tanımlanmamış olan ile sorunları vardı ikincisini yaptığımda ilk cevabı kaybedeceğim. Örneğin, ilk api çağrısı, kullanıcı bilgisini almak için/me. Daha sonra/fb-id/fotoğraflarını çağırabilir ve fotoğraf çekebilirim, fakat eğer fotoğraf api çağıranın içinde başka bir işleve çağrı yaparsam, sadece o yanıtı orijinal/ben cevabını kaybettiğime de değinebilirim. Yanıtı geri aramadan alabilirsem, gerektiğinde onu aktarabilirdim. Yanıtın sadece geri aramada geçerli olduğunu anlıyorum, bu yüzden asenkronizasyon hesaba katılırken geri arama dışında nasıl geçerli hale getirebilirim?

cevap

24

Herkes bunu anladım. Çok uzun sürdü ve çok farklı sayfalar okudum. Ne dediğimi tüm geri bildirimler ve kapanışlarla yapmak istediğimi söyledim. İlk olarak geri arama sorununu ele alacağım. FB.api işlevi eşzamansız olduğundan, ne zaman döneceğini asla bilemezsiniz. Javascript'i durdurabilir veya bir zamanlayıcı ayarlayabilirsiniz, ancak bunu yapmak için korkunç bir yoldur. Bir geri aramaya ihtiyacın var. Aslında FB.api bir geri arama kullanıyor. İkinci parametre olarak anonim işlev budur. Yaptığım şey, fbUser adlı başka bir işlev yaratmaktı ve bir geri arama kullanmıştı. İşte yaptığım şey:

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

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

StartThis işlevi, olumlu bir Facebook auth yanıtında çağrılır. Ardından geri arama özelliği olan fbUser işlevini çağırır. Geri arama geri çağrıyı FB.api işlevinden döndürür. StartThis bu geri dönüşümü model olarak adlandırılan döndürme değeriyle kullandığı için, geri arama geri dönene kadar diğer kod yürütülmez. Daha fazla tanımlanmamış sorun yok. Bu işlevler, Facebook yanıtımı görüntüleyenler için sadece sarmalayıcılar. Çok fazla soyutlama katmanı eklemiş olabilirim, ama cevabın etrafından geçmek istiyorsanız bu yoldur. İkinci olarak bu yanıtı başka bir görünüme aktarmak istedim. Örneğin, bir görünüm temel bilgileri (fbUser'den gelen yanıtı kullanarak) yükler. Şimdi bunu fotoğraf yükleyen başka bir görünüme aktarmak istiyorum (bunun en iyi MVC uygulamaları olmadığını biliyorum, fakat Facebook'u kullanarak Model üzerinde çok fazla kontrol sahibi değilim). Olsa sorun vardı ben bir sonraki görünüm için orijinal yanıtı geçemedim çünkü FB.api this için geri arama işlevinin içinde bulunduğum nesne değil Window için başvuruyor. Çözüm: kapanır. Bunu mükemmel bir şekilde açıklamayacağım ama bir kapanış, anonim bir işlevin içinde hala bir referansı olan bir fonksiyonun içindeki yerel bir değişkendir. İşte neden bahsettiğimi göstermek hangi benim çözümdür:

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

fonksiyon loadPhoto bir fotoğraf görünümü yüklemek için bir sarıcı (Ben omurga farklı görünümleri yükleme ile bana yardımcı olabilir biliyorum ama tek sorunu en uğraşmaktı bir zaman). Fotoğraf api çağrısını model olarak, bir ofset olarak bir sayı ve origanl yanıtını alır. Bu işlevdeki ilk satır bunu yerel bir değişkene ayarlar.Bu, anonim geri çağırma işlevinin içinde, bunun çağrıldığı nesneyi referans olarak kullanmamı sağlıyor.

Umarım bu, çözüme ulaşmak için çok fazla saat ve çok fazla test süresi harcadığım gibi birine yardımcı olabilir. Geri aramaların veya kapanışların nasıl çalıştığını bilmiyorsanız, aradığınız bilgiyi bulmak zordur.

+0

Teşekkür ederiz! Tam olarak aynı durumda bana yardımcı oldu! –

İlgili konular