为什么我可以获得console.log(变量)来给出我的值而不是返回变量?

时间:2016-07-25 14:54:45

标签: javascript json d3.js

在我的代码中,我使用d3.json从json加载数据 - 并且为了使其工作,我在加载数据后调用另一个函数并将json传递到那里进行处理。这似乎是有效的,但仍然拒绝返回任何东西,但" undefined"。

我的代码:

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

我使用GetDataFromJson()在Firefox Firebug中运行此操作并使用上面的代码,我只是得到了#34; undefined&#34;在控制台中。如果我在return语句之前添加一行console.log(myTotal),我得到&#34; undefined&#34;和&#34; 37.5&#34;返回为2个单独的行 - 37.5是我解析的数据中的正确值。

为什么我的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
  }
]

2 个答案:

答案 0 :(得分:1)

d3.json是一个异步(非阻塞)函数。这意味着它被调用,但程序流程仍在运行。因此,GetDataFromJson实际完成后d3.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

注意:您可以找到使@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Retrieve the ImageView having id="star_container" (where to put the star.png image): ImageView myImageView = (ImageView) findViewById(R.id.star_container); // Create a Bitmap image startin from the star.png into the "/res/drawable/" directory: Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star); // Create a new image bitmap having width to hold 5 star.png image: Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth() * 5, myBitmap.getHeight(), Bitmap.Config.RGB_565); /* Attach a brand new canvas to this new Bitmap. The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: 1) a Bitmap to hold the pixels. 2) a Canvas to host the draw calls (writing into the bitmap). 3) a drawing primitive (e.g. Rect, Path, text, Bitmap). 4) a paint (to describe the colors and styles for the drawing). */ Canvas tempCanvas = new Canvas(tempBitmap); // Draw the image bitmap into the cavas: tempCanvas.drawBitmap(myBitmap, 0, 0, null); tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth(), 0, null); tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 2, 0, null); tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 3, 0, null); tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 4, 0, null); myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap)); } 请求同步(阻止)并使其按预期方式工作的方法,但这不是一个好习惯。

如果您想了解更多关于事件循环的工作原理,我强烈推荐Philip Roberts在2014年JSConf EU上的演讲,名为"What the heck is the event loop anyway?"

答案 1 :(得分:0)

您的函数GetDataFromJson()正在返回undefined,因为这是JavaScript中的预期行为:如果函数未指定一个返回值,则undefined是“默认”返回值,并且函数GetDataFromJson()没有任何return

如果两个函数都有效(即异步代码没有问题),在GetDataFromJson()函数中你应该改变它:

NewValue(jsonData);

为此:

return NewValue(jsonData);

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