1

些細なことを尋ねるのはばかげていると思いますが、ベストプラクティスの答えが本当に欲しいです(他に何も可能でない限り、「setTimeout」ソリューションを探していません-そうであるとは思えませんが)。

簡単な概要: コールバック内からプッシュしたい配列があります。配列にデータを入力したら、コールバックの外でそれを使用したいと思います。

実際の使用: 都市の配列があり、Google の API を使用してそれらをジオコーディングし、結果のすべての LatLng を配列​​に入力したいと考えています。後で、それらを使用してマーカー オブジェクトを作成し、クラスタラーに追加します。

coder = new google.maps.Geocoder();
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
all_the_pins = Array();
for(i in $places){
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);
                break;
        }
    });
}
console.log(all_the_pins);

all_the_pinsEDIT:問題を明確にするために:問題はスコープの問題でも、変数がグローバルかどうかの問題でもありませんall_the_pins。コールバック内で調べると、それが同じ変数であることがわかります(これはにプッシュされています)。console.log問題は、プッシュがコールバック内で発生するため、以下で実行される前に発生しないことです。

4

3 に答える 3

1

あなたの質問は明確ではないので、all_the_pins arrayすべてのジオコード呼び出しが完了したときに を処理したいと推測します。ジオコード関数の呼び出しは非同期であるため、すべてのジオコード呼び出しがいつ完了したかを追跡する必要があり、最終的な配列を使用できます。

もしそうなら、あなたは次のようにすることができます:

var coder = new google.maps.Geocoder();
var $places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
var all_the_pins = Array();
var remaining = $places.length;
for (var i = 0, len = $places.length; i < len; i++)
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);
                break;
        }
        --remaining;
        if (remaining == 0) {
            // all_the_pins data is set here
            // call a function and pass the array to it or put your
            // code here to process it
            console.log(all_the_pins);
        }
    });
}

for注:配列を反復するための適切なタイプのループ にも変更しました。for (var i in xxx)配列の要素ではなく、オブジェクトのプロパティを反復するためのものです。

于 2012-05-30T00:47:34.427 に答える
1

いいえ、ここでは setTimeout はまったく役に立ちません。いくつかの非同期リクエストがあり、それらすべてがコールバックしたときに何かをしたい場合、唯一の可能性はカウンターです。最後のコールバックの後、オープン リクエストの数は null になります。次に、必要なものを実行します。

var coder = new google.maps.Geocoder();
var places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
var all_the_pins = [];
for (var i=0; i<places.length)
    coder.geocode({address:places[i]}, function(res, stat){
        if (stat == 'OK')
            all_the_pins.push(res[0].geometry.location);
        else
            all_the_pins.push(stat);

        // counter is length of results array:
        if (all_the_pins.length >= places.length) {
            console.log(all_the_pins);
        }
    });
于 2012-05-30T00:49:20.203 に答える
0

コードの残りの部分を別のコールバック内に置くことはできますか? x 回 (つまり、入力配列の長さ) 呼び出された後にのみ実行される関数を設定します。

coder = new google.maps.Geocoder();
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS'];
all_the_pins = Array();

function myCallback(count, totalCount, all_the_pins) {
    if (count != totalCount) return;

    console.log(all_the_pins);
}

count = 1;

for(i in $places){
    var $place = $places[i];
    coder.geocode({address:$place}, function(res, stat){
        switch(stat){
            case 'OK':
                all_the_pins.push(res[0].geometry.location);

                myCallback(count, $places.length, all_the_pins);
                count++;
                break;
        }
    });
}
于 2012-05-30T00:47:26.077 に答える