0

重複の可能性:
関数を setTimeout にループで渡す: 常に最後の値?

問題に対処するにはクロージャーを使用する必要があることはわかっていますが、その方法がわかりません。サーバーからデータを取得する機能があります。

function loadGraph(chartDataStreams) { //length of chartDataStreams is two

  initCharts(); //init charts area
  for (c in chartDataStreams) {
    var chartData = [];
    alert(c); // says : 0, then 1
    getDataFromServer(chartDataStreams[c].x, chartDataStreams[c].y,function (data) {
       for (d in data.datapoints) {
         var item = { date: new Date(data.datapoints[d].at), value:data.datapoints[d].value };
         chartData.push(item);
        }
      alert(c); // says: 1 then 1
      updateGraphData(chartData); 

    });
  }
}

この関数では、グラフ データ プロバイダーを chartData で更新する updateGraphData を呼び出す必要があります。問題は、chartData に実際のデータだけでなく、前のループ サイクルのデータも含まれていることです。これはクロージャーを使用する適切な場所だと思いますが、方法がわかりません.. 何かアイデアはありますか?

//編集: 誤って chartData の宣言を getDataFromServer 関数の外に置いてしまいましたが、まだ 1 つの問題があります。編集されたコードを確認してください。2 番目のアラートから、1,1 だけでなく、0 と 1 を言いたい

4

1 に答える 1

1

chartData外部ではなく、コールバック内で をインスタンス化します。

function loadGraph(chartDataStreams) {
    initCharts();
    for (c in chartDataStreams) {
        getDataFromServer(chartDataStreams[c].x, chartDataStreams[c].y, function (data) {

            var chartData = []; // RIGHT HERE

            for (d in data.datapoints) {
                var item = {
                    date: new Date(data.datapoints[d].at),
                    value: data.datapoints[d].value
                };
                chartData.push(item);
            }
            updateGraphData(chartData);
        });
    }
 }

このようにして、各コールバックは、呼び出されたときに独自の新しいchartData配列を取得します。

ブロックは JavaScript では変数のスコープを作成せず、関数のみを作成するため、外側chartDataは外側の関数にスコープされ、ループの反復ごとに上書きされました。

その最後の上書きは、すべてのコールバックが最終的に呼び出されたときに使用したものであったため、すべてのデータがその共有配列に格納されました。

于 2013-01-29T16:57:01.303 に答える