无法将值推送到数组

时间:2016-02-25 15:28:57

标签: javascript arrays d3.js

我创建了一个简单的脚本来读取JSON文件并将其重组为d3.js接受的状态。

不要过多关注重组,它按预期工作。我唯一的问题是,尽管我将不同的节点对象添加到节点数组,并将不同的链接对象添加到链接数组,但console.logs告诉我两个数组最后都是空的。

function loadJSON(file, callback) {

  var xobj = new XMLHttpRequest();
  xobj.overrideMimeType("application/json");
  xobj.open('GET', file, true); // Replace 'my_data' with the path to your file
  xobj.onreadystatechange = function() {
    if (xobj.readyState == 4 && xobj.status == "200") {
      // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
      callback(xobj.responseText);
    }
  };
  xobj.send(null);
}

var nodes = new Array();
var links = new Array();

function load(jsonPath) {


  loadJSON(jsonPath, function(response) {

    var actual_JSON = JSON.parse(response);

    //create array which will hold all the nodes and links

    //we create a var for the stringified nodes
    var stringifiedJson = JSON.stringify(actual_JSON.nodes);
    //we trim the string of the beginning and ending brackets
    stringifiedJson = stringifiedJson.substring(2, stringifiedJson.length - 2);


    //restructuring nodes

    //logic for separating all the nodes
    var nodeArray = stringifiedJson.split(",");
    for (var i = 0; i < nodeArray.length; i++) {
      //for every separated node, now we separate the ID from the IP
      var currArr = nodeArray[i].split(":");
      //currArr[0] is id, currArr[1] is IP
      var node = {
        id: currArr[0].substring(1, currArr[0].length - 1),
        ip: currArr[1].substring(1, currArr[1].length - 1)
      };


      //node is added to array of nodes

      nodes.push(node);
      console.log(node);
    }

    //restructuring links

    //make a variable of the links object
    var objectWithLinks = actual_JSON.links[0];

    //put all the keys of that objects in an array Keys, to be able to access the values later
    var keys = [];
    for (var k in objectWithLinks) keys.push(k);
    //For each key in the links object, we see how many destinations it has, and we restructure it so a link has one source and one destination 
    for (var i = 0; i < keys.length; i++) {
      //we check how many destinations the link has, and start seperating them
      for (var key in objectWithLinks[keys[i]].dst_ips) {
        var trimmedKey = key.substring(1, key.length - 1);
        var sourceKeyAsNumber = Number(keys[i]);
        var destinationKeyAsNumber = Number(key);
        var link = {
          source: sourceKeyAsNumber,
          target: destinationKeyAsNumber
        };


        //link is added to array of links

        links.push(link);
        console.log(link);
      }
    }

  });

}
load("gas.json");
console.log("length of links", links.length);
console.log("length of nodes", nodes.length);

1 个答案:

答案 0 :(得分:1)

这里的想法是在读取文件时调用回调。

因此你有这样的事情:

//Note that I have just stripped the code to highlight the concept. 
//The code will not run as is

//statement 1
loadJSON(path, function(){
   //statement 2
   nodes.push(node);
});

//statement 3
console.log(nodes.length);

如果您尝试访问回调之外的值,则无法保证语句2 语句3 的执行顺序。如果语句3 语句2 之前执行,您将获得一个空数组,这就是本例中发生的情况。

要解决此问题,请访问回调中的值。

//statement 1
loadJSON(path, function(){
   //statement 2
   nodes.push(node);

   //statement 3
   console.log(nodes.length);
});

在您提供的代码中,它将如下所示:

function loadJSON(file, callback) {

  var xobj = new XMLHttpRequest();
  xobj.overrideMimeType("application/json");
  xobj.open('GET', file, true); // Replace 'my_data' with the path to your file
  xobj.onreadystatechange = function() {
    if (xobj.readyState == 4 && xobj.status == "200") {
      // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
      callback(xobj.responseText);
    }
  };
  xobj.send(null);
}

var nodes = new Array();
var links = new Array();

function load(jsonPath) {


  loadJSON(jsonPath, function(response) {

    var actual_JSON = JSON.parse(response);

    //create array which will hold all the nodes and links

    //we create a var for the stringified nodes
    var stringifiedJson = JSON.stringify(actual_JSON.nodes);
    //we trim the string of the beginning and ending brackets
    stringifiedJson = stringifiedJson.substring(2, stringifiedJson.length - 2);


    //restructuring nodes

    //logic for separating all the nodes
    var nodeArray = stringifiedJson.split(",");
    for (var i = 0; i < nodeArray.length; i++) {
      //for every separated node, now we separate the ID from the IP
      var currArr = nodeArray[i].split(":");
      //currArr[0] is id, currArr[1] is IP
      var node = {
        id: currArr[0].substring(1, currArr[0].length - 1),
        ip: currArr[1].substring(1, currArr[1].length - 1)
      };


      //node is added to array of nodes

      nodes.push(node);
      console.log(node);
    }

    //restructuring links

    //make a variable of the links object
    var objectWithLinks = actual_JSON.links[0];

    //put all the keys of that objects in an array Keys, to be able to access the values later
    var keys = [];
    for (var k in objectWithLinks) keys.push(k);
    //For each key in the links object, we see how many destinations it has, and we restructure it so a link has one source and one destination 
    for (var i = 0; i < keys.length; i++) {
      //we check how many destinations the link has, and start seperating them
      for (var key in objectWithLinks[keys[i]].dst_ips) {
        var trimmedKey = key.substring(1, key.length - 1);
        var sourceKeyAsNumber = Number(keys[i]);
        var destinationKeyAsNumber = Number(key);
        var link = {
          source: sourceKeyAsNumber,
          target: destinationKeyAsNumber
        };


        //link is added to array of links

        links.push(link);
        console.log(link);
      }
    }
    console.log("length of links", links.length);
    console.log("length of nodes", nodes.length);
  });    
}
load("gas.json");
相关问题