为什么我可以获取console.log(变量)来给出我的值,而不能返回变量

Why can I get console.log(variable) to give my value but not return variable?

本文关键字:变量 我的 返回 不能 获取 我可以 console log 为什么      更新时间:2023-09-26

在我的代码中,我使用d3.json从json加载数据,为了让它正常工作,我在加载数据后调用另一个函数,并将json传递到那里进行处理。这似乎是有效的,但仍然拒绝返回除"未定义"之外的任何内容。

我的代码:

function GetDataFromJson() {
      var jsonData;
    d3.json("http://localhost:8000/pipeline.json", function(dataFromServer){
        jsonData = dataFromServer; 
          NewValue(jsonData);
     });
    }

function NewValue(data){
  var jsonData = data;
  headers = ["Won"];
  var myTotal = 0;
      chunks = (headers.map(function(priceRange) {
          return jsonData.map(function(d) {
            return {y: +d[priceRange]};
          });
      }));
      var myTarget = 10000000;
      chunks.forEach( function (arrayItem)
          {
            var l = 12;
            for(var i = 0; i < l; i++) {
              myTotal += arrayItem[i].y;
            };
          });
      myTotal = myTotal/myTarget*100;
      return myTotal;
}

我在FirefoxFirebug中使用GetDataFromJson()运行这个程序,按照上面的代码,我只是在控制台中得到了"未定义"。如果我在return语句之前添加一行console.log(myTotal),我会得到"undefined"answers"37.5",它们分别作为两行返回——37.5是我在中解析的数据的正确值

为什么return不将myTotal作为函数的结果,而console.log()是?

添加Json数据

[
  {
    "Month": "Jan",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 0,
    "Negotiating": 0,
    "Won": 1000000,
    "Lost": 350000
  },
  {
    "Month": "Feb",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 0,
    "Negotiating": 0,
    "Won": 750000,
    "Lost": 2750775
  },
  {
    "Month": "Mar",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 0,
    "Negotiating": 250000,
    "Won": 2000000,
    "Lost": 750000
  },
  {
    "Month": "Apr",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 0,
    "Negotiating": 1375000,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "May",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 750000,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Jun",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 325000,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Jul",
    "Prospecting": 0,
    "Qualifying": 50000,
    "Demonstrating": 1000000,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Aug",
    "Prospecting": 10000,
    "Qualifying": 35000,
    "Demonstrating": 0,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Sep",
    "Prospecting": 12250,
    "Qualifying": 22500,
    "Demonstrating": 0,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Oct",
    "Prospecting": 0,
    "Qualifying": 0,
    "Demonstrating": 0,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Nov",
    "Prospecting": 100000,
    "Qualifying": 325000,
    "Demonstrating": 750000,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  },
  {
    "Month": "Dec",
    "Prospecting": 120000,
    "Qualifying": 370500,
    "Demonstrating": 670000,
    "Negotiating": 0,
    "Won": 0,
    "Lost": 0
  }
]

d3.json是一个异步(非阻塞)函数。这意味着它会被调用,但程序的流程会继续运行。因此,GetDataFromJsond3.json实际完成之前返回,d3.json在稍后通过HTTP请求获取JSON数据后返回。

具有回调功能的解决方案:

// Pass a "callback" function that will get called once
// the asynchronous task of downloading JSON data is finished.
function GetDataFromJson(callback) {
    var jsonData;
    d3.json("http://localhost:8000/pipeline.json", function(dataFromServer){
        jsonData = dataFromServer; 
        callback(NewValue(jsonData));
    });
    // You don't have this return statement in your code, but it's implied.
    // This line gets called before d3.json is finished.
    // It's the line that gives you the undefined when you do 
    // console.log(GetDataFromJson(...));
    // To test this, try changing it to return "foo",
    // you will get "foo" instead of undefined.
    return;
}

这样称呼它:

// The inline callback function we pass will get called
// once the async task is finished. Then we can handle the result.
GetDataFromJson(function(result) {
    console.log(result);
});

注意:您可以找到使HTTP请求同步(阻塞)并按预期方式工作的方法,但这不是一个好的做法。

如果你想了解更多事件循环是如何工作的,我强烈推荐菲利普·罗伯茨在2014年欧洲联合委员会会议上的演讲,题为"事件循环到底是什么?"。

函数GetDataFromJson()返回undefined,因为这是JavaScript中的预期行为:如果函数没有指定一个返回值,则undefined是"默认"返回值,而函数GetDataFromJson()没有任何return

假设两个函数都能工作(即异步代码没有问题),那么在GetDataFromJson()函数中,您应该更改以下内容:

NewValue(jsonData);

为此:

return NewValue(jsonData);

因此,该函数可以返回与您使用console.log看到的值相同的值。