Javascript 尝试解析JSON时,JSON中位于位置0的意外标记u

Javascript 尝试解析JSON时,JSON中位于位置0的意外标记u,javascript,json,d3.js,Javascript,Json,D3.js,我试着用d3画一棵树 当我试图解析它时,在JSON中的位置0处获取error:Uncaught SyntaxError:Unexpected token u 在JSON.parse()处 测试时:44 代码如下: function getTree() { $.ajax({ url: "/Test/FPTree", dataType: 'json', success: function (data) {

我试着用d3画一棵树

当我试图解析它时,在JSON中的位置0处获取error:Uncaught SyntaxError:Unexpected token u 在JSON.parse()处 测试时:44

代码如下:

function getTree() {
        $.ajax({
            url: "/Test/FPTree",
            dataType: 'json',
            success: function (data) {
                return data;
            }
        })
    }
    var treeData = [];

    treeData.push(JSON.parse(getTree()));

    var margin = { top: 20, right: 120, bottom: 20, left: 120 },
        width = 960 - margin.right - margin.left,
        height = 500 - margin.top - margin.bottom;

    var i = 0;

    var tree = d3.layout.tree()
        .size([height, width]);

    var diagonal = d3.svg.diagonal()
        .projection(function (d) { return [d.y, d.x]; });

    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0];

    update(root);

    function update(source) {

        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        nodes.forEach(function (d) { d.y = d.depth * 180; });

        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) {
                return "translate(" + d.y + "," + d.x + ")";
            });

        nodeEnter.append("circle")
            .attr("r", 10)
            .style("fill", "#fff");

        nodeEnter.append("text")
            .attr("x", function (d) {
                return d.children || d._children ? -13 : 13;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", function (d) {
                return d.children || d._children ? "end" : "start";
            })
            .text(function (d) { return d.name; })
            .style("fill-opacity", 1);

        var link = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", diagonal);
    }
这是我从服务器上得到的JSON(使用邮递员获取),它是有效的:

{
  "name": null,
  "parent": null,
  "children": [
    {
      "name": "A",
      "parent": null,
      "children": [
        {
          "name": "B",
          "parent": "A",
          "children": [
            {
              "name": "C",
              "parent": "B",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}
和来自控制器动作的代码

 [HttpGet]
    public ContentResult FPTree()
    {
        FPTree Tree = new FPTree();
        Tree.Add(new List<string> { "A", "B", "C" });

        var settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> { new FPTreeConverter() },
            Formatting = Formatting.Indented
        };
        return Content(JsonConvert.SerializeObject(Tree.root, settings), "application/json");
    }
[HttpGet]
公共内容结果FPTree()
{
FPTree-Tree=新的FPTree();
添加(新列表{“A”、“B”、“C”});
var设置=新的JsonSerializerSettings
{
转换器=新列表{new FPTreeConverter()},
格式化=格式化。缩进
};
返回内容(JsonConvert.SerializeObject(Tree.root,settings),“application/json”);
}

您正在调用函数并在实际检索数据之前“使用”数据

您应该在AJAX成功时调用的回调函数中使用promise返回的数据,而不是在它之外

换句话说:调用getTree(),因此启动AJAX请求,并尝试解析调用后立即返回的数据。但是,AJAX请求需要一些时间(这取决于许多事情,但通常不到一秒钟)来处理和返回数据,因为它是异步的。调用成功回调时,另一个函数已经停止,因为getTree()返回的数据是未定义的(因此在解析错误中出现“u”)

试着这样做:

    var tree = d3.layout.tree().size([height, width]);

    function getTree() {
        $.ajax({
            url: "/Test/FPTree",
            dataType: 'json',
            success: function (data) {

                var treeData = [];
                treeData.push(JSON.parse(data));

                var margin = { top: 20, right: 120, bottom: 20, left: 120 },
                    width = 960 - margin.right - margin.left,
                    height = 500 - margin.top - margin.bottom;
                var i = 0;

                var diagonal = d3.svg.diagonal()
                    .projection(function (d) { return [d.y, d.x]; });
                var svg = d3.select("body").append("svg")
                    .attr("width", width + margin.right + margin.left)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
                root = treeData[0];
                update(root);
            }
        })
    }

    function update(source) {
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        nodes.forEach(function (d) { d.y = d.depth * 180; });

        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) {
                return "translate(" + d.y + "," + d.x + ")";
            });

        nodeEnter.append("circle")
            .attr("r", 10)
            .style("fill", "#fff");

        nodeEnter.append("text")
            .attr("x", function (d) {
                return d.children || d._children ? -13 : 13;
            })
            .attr("dy", ".35em")
            .attr("text-anchor", function (d) {
                return d.children || d._children ? "end" : "start";
            })
            .text(function (d) { return d.name; })
            .style("fill-opacity", 1);

        var link = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", diagonal);
    }
看起来在您的getTree()函数中实际上没有返回任何内容。它返回
undefined
,这就是您收到错误消息的原因。问题在于ajax调用中的success函数,返回数据,但只返回传递给success参数的匿名函数。getTree()函数实际上会立即返回,因为ajax调用是异步的。相反,您应该使用回调函数。也就是说,将一个函数传递到getTree()函数中,该函数在完成时将与数据一起调用。这里有一个例子

function getTree(callback) {
    $.ajax({
        url: "/Test/FPTree",
        dataType: 'json',
        success: function (data) {
            callback(data);
        }
    })
}

getTree(function(data) {

    var treeData = [];

    treeData.push(JSON.parse(getTree()));

    var margin = { top: 20, right: 120, bottom: 20, left: 120 },
    width = 960 - margin.right - margin.left,
    height = 500 - margin.top - margin.bottom;

    var i = 0;

    var tree = d3.layout.tree()
    .size([height, width]);

    var diagonal = d3.svg.diagonal()
    .projection(function (d) { return [d.y, d.x]; });

    var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0]

    update(root)
});

您的JSON是“未定义”的,您在调用JSON之前没有等待结果返回。parse
getTree
正在调用一个
ajax
函数,并且没有返回任何内容,因此您的
JSON.parse
失败。您需要做的是将所有需要数据的逻辑封装到函数中,并在收到数据后从
ajax
success
调用它