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); 

    });
  }
}

在此函数中,我需要调用 updateGraphData,它使用 chartData 更新图形数据提供程序。问题是在 chartData 我不仅有实际数据,还有来自上一个循环周期的数据。我认为这是使用闭包的正确位置,但我不确定如何......你有什么想法吗?

//edit: 我错误地将chartData的声明放在了getDataFromServer函数之外,但我还有一个问题:检查编辑后的代码。从第二个警报我想说 0 和 1,而不仅仅是 1,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 回答