在我的代码中,我使用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
}
]
答案 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
看到的相同值。