0

Javascript で同期の問題が発生しています。以下のコード。相互の友達を取得するための呼び出しを行うと、私の関数はまだ API コールバックを介して配列を埋めていますが、"Quite a bunch: 0"の出力 は - の出力の前に行われます。console.log(friendID +" -> " + mutualfriends.data.length);

これはコールバック/非同期の問題に違いないことはわかっていますが、対処方法がわかりません。理由で配列を埋めています - 次の部分のためにそれを埋める必要があります。

コード:

function getMutualFriends(friendID)
{
  //console.log(response.data[i].id);
  try{

           FB.api('/me/mutualfriends/'+friendID, function(mutualfriends) {
             //console.log(mutualfriends);
             //console.log(mutualfriends.data.length);

             console.log(friendID +" -> " + mutualfriends.data.length);
             mutualFriendsList.push([friendID,mutualfriends.data.length]);
           });
    }
  catch(err){
    console.log('error caught: ' +err);
  }

}

function getFriendsList()
{
  FB.getLoginStatus(function(response){   
    FB.api('/me/friends', function(response) {

         for(i=0; i<response.data.length;i++)
         {
           var friendID = response.data[i].id;
           console.log(friendID);
           friendsList.push(friendID);
         }

         console.log('Interesting, we gathered: '+friendsList.length+' friends,');

         console.log('lets check mutual friends now');

        for(j=0; j<friendsList.length;j++)
        {
          getMutualFriends(friendsList[j]);
        }

        console.log('Quite a bunch: ' + mutualFriendsList.length);

        });//friends
  });
}
4

3 に答える 3

3

おそらく、「事後条件」コードをコールバックに変えたいと思うでしょう。

それで、あなたは今どこにいるのですか:

for(j=0; j<friendsList.length;j++)
{
  getMutualFriends(friendsList[j]);
}

console.log('Quite a bunch: ' + mutualFriendsList.length);

次のようなものが必要です。

for(j=0; j<friendsList.length;j++)
{
  getMutualFriends(friendsList[j], function(mutualFriendsList) {
    console.log('Quite a bunch: ' + mutualFriendsList.length);
  });
}

このように設定すると、getMutualFriends関数は結果を取得したらコールバックを呼び出すことができます。

function getMutualFriends(friendID, callback)
{
   FB.api('/me/mutualfriends/'+friendID, function(mutualfriends) {
     mutualFriendsList.push([friendID,mutualfriends.data.length]);
     callback(mutualFriendsList);
   });
}

これにより、 への呼び出しごとにコールバックが 1 回実行されますgetMutualFriendsコールバックをすべてのフレンドに対して 1 回だけトリガーする場合は、概念をさらに拡張する必要があります。

更新

上記の「フレンドごと」のコールバックを @RGDev の条件と組み合わせて、最後のフレンドを検出できます。

for(j=0; j<friendsList.length;j++)
{
  getMutualFriends(friendsList[j], function(mutualFriendsList) {
    if (mutualFriendsList.length == friendsList.length) {
      console.log('Quite a bunch: ' + mutualFriendsList.length);
    }
  });
}
于 2013-01-09T15:06:18.187 に答える
0

getMutualFriends は (FB.api を呼び出すことによって) 独自に非同期呼び出しを行っているため、それが完了するまで MutualFriendsList を出力することはできません (実際には、getMutualFiends への呼び出しを何度も行っているため、すべての非同期呼び出しが完了するまで MutualFriendsList は正確ではありません)。処理)。

そのコレクションが非同期であることを当てにすることはできませんか? あなたがそれで何をしているのかわかりませんが、おそらく(例で画面に描画している場合) FB.api('/me/mutualfriends/' のコールバックのたびにそのコンポーネントの再描画を発行できます+friendID, ...) が完了しました。

過去に同様の問題がありましたが、単純な javascript 配列の代わりに backbone.js のコレクションを使用して解決しました。次に、リスナーをコレクションの add イベントにバインドし、オブジェクトが追加されるたびに友達の数を出力します。

幸運を、

于 2013-01-09T15:02:08.277 に答える
0

while ループを使用して、mutualFriendsList.length が friendsList.length と等しくなるまで待機できます。これは、すべての ajax 関数の return 関数が実行されたことを意味します。

次のようになります。

while(mutualFriendsList.length != friendsList.length)
{
console.log("Still Waiting");

 }
console.log('done')
// do your data processing 

少しエレガントではありませんが、うまくいくはずです

于 2013-01-09T15:06:09.620 に答える