0

私はグーグルマップコードでこの問題に取り組んでいますが、実際にはアーキテクチャ上の問題です。リクエストが多すぎるため、ある時点でグーグルマップは応答を制限し、その時点で私は遅れて別のリクエストをしたいのですが、function2をもう一度呼び出すと「配列が定義されていません」と表示されます。

function1() {
    var array = JSON.parse(xmlhttp.responseText);

    for (i; i < length; < i++) {
        function2(array[i].one, array[i].two);
    }

    function3() {
        //render directions
    }

    function2(start, end) {
        directionsService.route({
            origin: start,
            destination: end,
        },

        function (result, status) {
            if (status == google.maps.DirectionsStatus.OK)
                function3(result);
            else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT)
                var functionStr = "function2(array[i].one" + ',' + "array[i].two)";
            setTimeout(functionStr, 5000);
        });
    }

}
4

2 に答える 2

6

これは、コードの文字列を使用すると、setTimeout()について知らないグローバルスコープで実行されるためarrayです。iグローバルスコープも;について知りません。たとえそうだったとしても、の値はiとにかくもう有効ではありません。

次のように、関数コードを無名関数でラップすると機能するはずです。

setTimeout(function() {
    function2(start, end);
}, 5000);

これらの値は変数の変更から保護されているためstart、ここで簡単に再利用できることに注意してください。endi

ところで、これらのレートの問題を防ぐために、すべてのGoogleリクエストをシリアル化することを検討できます。つまり、リクエストを次々にシリアル化することを検討できます。

于 2013-03-26T10:46:23.680 に答える
0

setTimeoutの関数は、配列変数のスコープ内ではなく、別のスコープで実行されます。匿名関数でラップすることができます。

ここを参照してください: setTimeout()コールバックにパラメーターを渡すにはどうすればよいですか?

したがって、コードは次のようになります。

   function (result, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                function3(result);
            } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                setTimeout(function () {
                    function2(array[i].one, array[i].two);
                }, 5000);
            }
        });

if elseifステートメントのコードには、中括弧{}がないことに注意してください。これらを追加しました。

于 2013-03-26T10:49:23.177 に答える