javascript - Why can I get console.log(variable) to give my value but not return variable? -
in code i'm loading data json using d3.json - , in order working call function once data loaded , pass json across there processing. seems working, still refuses return "undefined".
my code:
function getdatafromjson() { var jsondata; d3.json("http://localhost:8000/pipeline.json", function(datafromserver){ jsondata = datafromserver; newvalue(jsondata); }); }
and
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 = 0; < l; i++) { mytotal += arrayitem[i].y; }; }); mytotal = mytotal/mytarget*100; return mytotal; }
i'm running in firefox firebug using getdatafromjson()
, code above as-is "undefined" in console. if add line console.log(mytotal)
before return statement "undefined" , "37.5" returned 2 separate lines - 37.5 being correct value data parsed in.
why isn't return giving mytotal result of function whereas console.log() is?
adding json data
[ { "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
asynchronous (non-blocking) function. means gets called, flow of program keeps running. therefore getdatafromjson
returns before d3.json
finished , d3.json
completes @ later time, once has fetched json data through http
request.
solution callback functions:
// pass "callback" function called once // asynchronous task of downloading json data finished. function getdatafromjson(callback) { var jsondata; d3.json("http://localhost:8000/pipeline.json", function(datafromserver){ jsondata = datafromserver; callback(newvalue(jsondata)); }); // don't have return statement in code, it's implied. // line gets called before d3.json finished. // it's line gives undefined when // console.log(getdatafromjson(...)); // test this, try changing return "foo", // "foo" instead of undefined. return; }
and call this:
// inline callback function pass called // once async task finished. can handle result. getdatafromjson(function(result) { console.log(result); });
note: can find ways make http
request synchronous (blocking) , make work way anticipated, it's not practice.
if you'd learn more how event-loop works, highly recommend talk philip roberts @ jsconf eu 2014, named "what heck event loop anyway?".
Comments
Post a Comment