【问题标题】:"Undefined" as a result of the assignment“未定义”作为分配的结果
【发布时间】:2015-09-10 18:45:36
【问题描述】:

我是 javascript 的新手。面临以下问题

var list = [];

initList(); // after this function I have some elements in `list`

var node = list[0]; //after the assignment firebug says `node` is undefined. `list[0]` is defined and contains object like {a:"value",b:"value1", ...}

我做错了什么? 我试图像var node = {}; 一样声明node。但它也不起作用。

这里是我的 initList 函数。希望会有人想要掌握它:))

function initList() {

    d3.json("./config.json", function (error, txt) {
        if (error) {
            console.debug(error)
        }
        txt.forEach(function (bop, i) {

            var nd = {};

            d3.json("./cgi-bin/getshmid.sh?key=" + (195951310 + bop.bop_id), function (error, shm) {
                if (error) {
                    console.debug(error)
                } else {
                    console.debug(bop, i)
                }


                d3.select("#tplace")
                    .append("h3")
                    .text("BOP's ID = " + bop.bop_id)

                var table = d3.select("#tplace")
                    .append("table")
                    .attr("id", "shmid_" + shm.id);

                var thead = table.append("tr")

                thead.append("td")
                    .text("Блоки детектирования, ID")
                thead.append("td")
                    .text("Текущее значение")
                thead.append("td")
                    .text("Предупредительная уставка")
                thead.append("td")
                    .text("Аварийная уставка")
                thead.append("td")
                    .text("Статус")
                thead.append("td")
                    .text("Превышение ПУ")
                thead.append("td")
                    .text("Превышение АУ")

                bop.BDs.forEach(function (bd, i) {
                    var tbody = table.append("tr")
                        .attr("class", "bd")
                    tbody.append("td")
                        .text(bd.index + 1)
                    tbody.append("td")
                        .attr("id", "val")
                    tbody.append("td")
                        .attr("id", "pz")
                        .attr("class", "edit " + (516 + i * 16) + "")
                    tbody.append("td")
                        .attr("id", "az")
                        .attr("class", "edit " + (518 + i * 16) + "")
                    tbody.append("td")
                        .attr("id", "status")
                    tbody.append("td")
                        .attr("id", "state_pz")
                    tbody.append("td")
                        .attr("id", "state_az")
                })

                nd = foo(shm.id);
                list.push(nd);
            })
        })
    })
};

function foo(id) {

    var node = {
        value: id,
        table: d3.select('#shmid_' + id),
        tr: d3.select('#shmid_' + id).selectAll(".bd"),
        bds: []
    };

    node.tr.each(function (d, i) {

        var bd = {};

        d3.select(this).selectAll("td").each(function (d, i) {

            switch (d3.select(this).attr("id")) {
                case 'val':
                    bd.val = d3.select(this);
                case 'pz':
                    bd.pz = d3.select(this);
                case 'az':
                    bd.az = d3.select(this);
                case 'status':
                    bd.status = d3.select(this);
                case 'state_pz':
                    bd.stpz = d3.select(this);
                case 'state_az':
                    bd.staz = d3.select(this);
            }
        });

        node.bds.push(bd);
    });

    return node;
};

【问题讨论】:

  • 你在你的函数中做var list = ...吗?
  • 你能显示initList函数吗?
  • 根据您指定的示例,您的节点结果不能未定义。
  • 请保持简单:在initList()console.log(list) 之后。不要让我们受制于充满我们无法运行的代码的屏幕和屏幕。

标签: javascript variable-assignment


【解决方案1】:

根据问题,问题在于initList 是一个异步函数。所以数组list不会被初始化。

var list = [];
initList(); //WARNING: asynchronous function!!!
var node = list[0]; 

你应该开始了解JavaScript Promises


这就是您的代码所发生的情况。第一行创建了一个名为list 的数组。第二行通过 ajax 调用初始化列表。但是在回调发生之前,第三行被执行给你一个错误,因为你试图获取一个未填充数组的第一个元素。
更新:

我还没有尝试过,但d3.promise plugin 看起来很简单。

var promise = d3.promise.json('test.json')
promise.then(function (data) {
    // call successful
}, function (error) {
    //call failed
});

【讨论】:

  • @ИосифСталин 不是单独的线程,而是异步。它会在您尝试访问列表之后结束。
  • JavaScript 是单线程的,你可能想读一下。 stackoverflow.com/q/598436/17447
  • @naveen @deceze 感谢主题!但是我能比Promises更简单地解决这个问题吗?
【解决方案2】:

为了更好地理解,我添加了以下代码。

function initList(){
	list.push(1);
	list.push(2);
}

var list = [];

initList(); // after this function I have some elements in `list`

var node = list[0]; //after the assignment firebug says `node` is undefined. `list[0]` is defined and contains object like {a:"value",b:"value1", ...}
console.log(node);

node 现在的值为 1。希望对您有所帮助。

还请检查代码中变量list 的范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2014-01-13
    • 2023-03-19
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多