0

So I'm running into concurrency issues with drawing a d3 graph. My page runs perfectly with one graph, but is having trouble with multiple. Here's the relevant code in fetching the json.

        json_fetching_id = "json/";
        json_fetching_id += json_ids.splice(0, 1);
        //here is where the d3 is grabbing the json file.
        d3.json(json_fetching_id, function(error, json){
            if (error) return console.warn(error);
            results = results.concat(json);
            callback(results); //the callback function draws the graphs.
         });
        console.info("Retrieving JSON file " + id);

If I have a breakpoint in the callback function, the code correctly executes with the expected display for multiple graphs, which leads me to believe it's a concurrency issue.

The above function is called in a for loop to each of the data entries I need to graph. What concerns me is that, when debugging, the debugger skips over the d3.json call, not executing the callback function. It goes through the entire for loop, not executing the callback, then executes the d3.json call after the for loop is complete -> which is where I think the concurrency issues are coming from. So my question is, is there a way to make sure to execute d3.json and its callback BEFORE going to the next item in the for loop rather than having it all execute at the end?

David Ma
  • 59
  • 11
  • 1
    See https://stackoverflow.com/questions/21842384/importing-data-from-multiple-csv-files-in-d3 and https://stackoverflow.com/questions/21293201/d3-loading-multiple-csv-data-files-in-a-folder – Lars Kotthoff Jul 27 '15 at 18:03

1 Answers1

1

The callback function executes asynchronously after the browser retrieves the JSON file. Meanwhile, your for loop continues. That's the expected behavior. You'll want to defer execution until after all files have been retrieved. Depending on your preference and what libraries you have available, you could use any Promises library or jQuery $.Deferred. If you want to stick to the D3.js ecosystem, Mike Bostock has released the queue.js library exactly for this purpose. That library's README.md includes an example that's precisely your use case.

Stephen Thomas
  • 13,843
  • 2
  • 32
  • 53
  • Turns out that the problem with the display is with the callback function I had. I might need more help on that at some point but your answer helped me learn a lot more about async functions. Thanks for sharing. – David Ma Jul 28 '15 at 14:08