【问题标题】:Same data adds twice to JavaScript table instead of adding two different things to the table相同的数据向 JavaScript 表添加了两次,而不是向表中添加了两个不同的东西
【发布时间】:2022-01-04 16:47:57
【问题描述】:

我有一个从 API 中提取并在表格中显示结果的程序。应该发生的是每一行应该是不同的数据。但是,当它运行时,它添加了两次 ID 为 4 的数据,完全跳过了 ID 为 3 的数据。起初,我认为我一定是在 GET 请求中搞砸了。我去检查,结果它正在获取数据,但没有将其添加到表中。我移动了所有代码以添加到 for 循环内的表中,但发生了同样的问题。如果有任何用处,我正在使用 Tomcat 来处理 API。

附件是我用来向表中添加行的函数。

function addRow(tableName, rowData) {
                for (var h = 0; h < rowData.length; h++) {
                    var ajaxRequest = new XMLHttpRequest();
                    ajaxRequest.onreadystatechange = function(){
                        if(ajaxRequest.readyState == 4){
                            if(ajaxRequest.status == 200){
                                let table = document.getElementById(tableName);
                                let row = table.insertRow(1);
                                var order = JSON.parse(ajaxRequest.responseText);
                                var cell0 = row.insertCell(0);
                                var cell1 = row.insertCell(1);
                                var cell2 = row.insertCell(2);
                                var cell3 = row.insertCell(3);
                                var cell4 = row.insertCell(4);
                                var cell5 = row.insertCell(5);
                                var cell6 = row.insertCell(6);
                                var cell7 = row.insertCell(7);
                                var cell8 = row.insertCell(8);
                                var cell9 = row.insertCell(9);
                                var cell10 = row.insertCell(10);
                                
                                cell0.innerHTML = order.id;
                                cell1.innerHTML = order.name;
                                cell2.innerHTML = order.time;
                                cell3.innerHTML = order.type;
                                cell4.innerHTML = order.creamerAmount + " " + order.creamerType;
                                cell5.innerHTML = order.sugarAmount;
                                cell6.innerHTML = order.coffeeType;
                                cell7.innerHTML = order.teaType;
                                cell8.innerHTML = order.hotChocolateType;
                                cell9.innerHTML = order.smoothieType;
                                cell10.innerHTML = order.protein;
                            } else {
                                //I'm aware this is bad, not sure how to handle it otherwise though...
                                h--;
                            }
                        }           
                    }
                    ajaxRequest.open('GET', 'http://localhost:13760/cafe/cafe/orders/' + rowData[h]);
                    ajaxRequest.send();
                }
                
            }   ```

【问题讨论】:

  • 由于hoisting,您的脚本中只有一个 ajaxRequest。不要使用旧的var,而是使用letconst
  • 那你为什么要发送rowData.length 请求而不是一次获得所有请求?
  • @Andreas 我忘了在问题中提到这一点,rowData 是一个我可能应该重命名的数组,它获取所有需要放在桌面上的所有 id,一次全部获取它们而无需这导致了性能问题,使得整个事情几乎无法使用,因为它试图每秒执行数百个 GET 请求,其中许多是空的。

标签: javascript html ajax html-table


【解决方案1】:

看起来安德烈亚斯是对的。
试试const ajaxRequest = ... 而不是var ajaxRequest = ...

我很难详细解释这里发生了什么。我的猜测如下:
如上所述,您使用相同的 ajaxRequest,就好像它会在 for 循环之前声明一样。
其次,由于请求是异步的,它在主线程代码完成后从事件循环中发送。这意味着它将请求发送到 id = 4 两次。

我仍然可能在细节上犯错(如果我错了,请纠正我),但将 var 更改为 const 应该会有所帮助。你试过了吗?

【讨论】:

  • "...如果它会在 for 循环之前声明。"- 因为这正是这里发生的事情。这就是提升。
  • @Andreas,同意,这就是我的意思,但我的解释不够清楚。问题是,在那之后它会如何行动。我有一个版本,它可以创建第一个 XHR 对象,发送请求,然后创建第二个并发送,之后它可以分别使用第一个和第二个的 onreadystatechange,尽管在变量中我们只引用最后一个......这显然不是它的工作原理。当然,你的答案是第一个也是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多