0

だから私はjavascriptでこのコードを書いた:

// Additional initialization code such as adding Event Listeners goes here
            FB.api('593959083958735/albums', function(response) {
                if(!response || response.error) {
                    // render error
                    alert("Noo!!");
                } else {
                    // render photos
                    for(i=0; i<response.data.length; i++){
                        var albumName = response.data[i].name;
                        var albumCover = response.data[i].cover_photo;
                        var albumId = response.data[i].id;
                        console.log(albumName);
                        FB.api( albumCover, function(response) {
                            if(!response || response.error) {
                                // render error
                                alert("Noo!!");
                            } else {
                               // render photos
                               $("ul").append('<li>'+
                                    '<a href="testFile.HTML" data-transition="slidedown">'+
                                    '<img src= "' + response.picture + '"  />'+
                                     '<h2>' + albumName + '</h2>'+
                                     '<p> Test Paragraph</p>'+
                                     '</a>'+
                                     '</li>')
                                .listview('refresh');
                            }
                        });                                 
                    }
                }
            });

私は Facebook の JavaScript API を使用して、Facebook ページのフォト アルバムを jquery モバイル ページにインポートし、それらを listView に配置しています。ご覧のとおり、listView を動的に作成します。listView には、サムネイルとしてアルバム coverPhoto と headline 、アルバム名があります。

しかし、ここで何かがひどく間違っています。上記のコードの結果はここで見ることができます

サムネイルはすべて正しいですが、アルバム名が間違っています。すべてのセルで、最後のアルバム名を取得します。ご覧のとおり、コードで console.log(albumName) を実行すると、すべての名前が正しく表示されます。しかし、FB.api への 2 回目の呼び出し内では、"albumName"変数は最後のアルバム名のみを保持します。

ここで何が起こっているのか分かりますか?それは文字通り私を夢中にさせます...

4

2 に答える 2

2

それは実際にiは問題ではなく、むしろalbumName.

ほとんどの JavaScript エンジンは非常に寛容で、varキーワードを使用して同じ変数を複数回宣言することができます。それがあなたがここでしていることです。キーワードは新しいスコープを導入しないことfor注意することが重要です。そのため、ループ内の各変数 ( albumNamealbumCover、およびalbumId) を (再) 宣言すると、同じ変数に以前に保存された値が上書きされます。

FB.api渡すコールバックがこれらのローカル変数を閉じ、(明らかに) 非同期で実行されるため、これは再びあなたを悩ませます。コールバックが実際に実行されるまでに、forループは完了し、これらの変数はすべて最後の値に設定されます。

もちろん、例外はalbumCover、すでに観察したようにです(サムネイルはすべて正しいと言っていました)。これは、この値をFB.api同期的に渡すためです。つまり、 loop 内で渡すため、閉じられません。

JavaScript のクロージャーをよりよく理解するには、「JavaScript クロージャーはどのように機能しますか?」を参照してください。

明確にするために:エパスカレロの答えはあなたのために問題を解決するはずです。匿名関数でロジックをラップすると、新しいスコープ (さまざまなシナリオで使用できる便利なトリック)albumName導入されるため、閉じられる などの値はコールバックごとに異なります。iそれ自体が問題の原因ではないことを指摘したかっただけです(コールバックがまったく終了しないためi)。

于 2013-06-19T17:47:01.920 に答える
2

i への参照しかない有名な i for ループの問題があるようです。

                for (var i = 0; i < response.data.length; i++) {  //added the var here
                    (function (i) {  //created a function
                        var albumName = response.data[i].name;
                        var albumCover = response.data[i].cover_photo;
                        var albumId = response.data[i].id;
                        console.log(albumName);
                        FB.api(albumCover, function (response) {
                            if (!response || response.error) {
                                // render error
                                alert("Noo!!");
                            } else {
                                // render photos
                                $("ul").append('<li>' +
                                    '<a href="testFile.HTML" data-transition="slidedown">' +
                                    '<img src= "' + response.picture + '"  />' +
                                    '<h2>' + albumName + '</h2>' +
                                    '<p> Test Paragraph</p>' +
                                    '</a>' +
                                    '</li>')
                                    .listview('refresh');
                            }
                        });
                    })(i);  //call the function with i
                }
于 2013-06-19T17:33:06.350 に答える