十年前我开发了一个 MS Access 桌面数据库应用程序,现在我尝试使用 node、electron 和 mysql 进行重建,现在我是一个正在恢复的 windows 用户。
在导入数据库的必要部分后,我首先在应用程序中重新创建最简单的表单:https ://imgur.com/a/oRfcsXw 。
问题出在数据控件的操作中(左下角),特别是在使用新记录按钮 (">+") 时。虽然它有时会正确地增加记录号(屏幕截图中的“336”),但有时它不会。当它粘住时,继续添加记录最终会使其突然赶上,然后最终再次粘住。调试指示原因是未正确报告rows.length
in 。newRecord()
似乎可以安全地假设这与我令人沮丧地无法完全理解异步执行、回调、promise 和 async/await 有关,尽管在过去的四天里我的智商适中并且对无数关于该主题的文章进行了猛烈抨击。我想我只需要看看一个如何做到这一点的例子,因为它适用于我的情况,然后我才能更好地掌握这个概念。所以请随意忽略下面这个 noobie 代码中的许多缺陷,其中一些他知道,并且我确定其中很多他不知道,并且只关注我如何获得准确的rows.length
.
<script>
var new_record = false;
var position = 0;
var last_record = 0;
var sql_columns = [];
var sql_values = [];
var mysql = require('mysql2/promise');
var bluebird = require('bluebird');
var pool = mysql.createPool({
host : 'localhost',
user : 'user',
password : 'password',
database : 'db',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
Promise: bluebird
});
async function getData() {
new_record = false;
const [rows, fields] = await pool.query('SELECT * FROM qryStudents');
last_record = rows.length - 1;
if (position > last_record) { position = last_record; }
refreshDataControl();
document.getElementById("student-id").value = rows[position].idsStudentID;
document.getElementById("first-name").value = rows[position].chrFName;
document.getElementById("last-name").value = rows[position].chrLName;
document.getElementById("ssn").value = rows[position].chrSSN;
if (rows[position].ysnActive == 1 || rows[position].ysnActive == true) {
document.getElementById("active").checked = true;
} else if (rows[position].ysnActive == 0 || rows[position].ysnActive == false) {
document.getElementById("active").checked = false;
}
document.getElementById("enrollment-address1").value = rows[position].chrAddress1;
document.getElementById("enrollment-address2").value = rows[position].chrAddress2;
document.getElementById("enrollment-city").value = rows[position].chrCity;
document.getElementById("enrollment-state").value = rows[position].chrState;
document.getElementById("enrollment-zip").value = rows[position].chrZIP;
document.getElementById("enrollment-phone").value = rows[position].chrPhone;
document.getElementById("lda-address1").value = rows[position].chrLDAAddress1;
document.getElementById("lda-address2").value = rows[position].chrLDAAddress2;
document.getElementById("lda-city").value = rows[position].chrLDACity;
document.getElementById("lda-state").value = rows[position].chrLDAState;
document.getElementById("lda-zip").value = rows[position].chrLDAZIP;
document.getElementById("lda-phone").value = rows[position].chrLDAPhone;
}
async function saveRecord() {
var sql;
var i;
if (sql_columns.length == 0) { return; }
if (new_record == true) {
sql = "INSERT INTO tblStudents SET ";
if (sql_columns.indexOf("ysnActive") == -1) {
sql_columns.push("ysnActive");
sql_values.push(document.getElementById("active").checked);
}
} else { sql = "UPDATE tblStudents SET "; }
for (i = 0; i < sql_columns.length; i++) {
if (i > 0) { sql = sql + ", "; }
sql = sql + sql_columns[i] + " = ?";
}
if (new_record == false) { sql = sql + " WHERE idsStudentID = ?;"; } else { sql = sql + ";"; }
await pool.query(sql, sql_values);
sql_columns = [];
sql_values = [];
}
function buildSQL(type, name, id) {
var index = sql_columns.indexOf(name);
if (index == -1) { sql_columns.push(name); }
if (type == "text") {
if (index == -1) { sql_values.push(document.getElementById(id).value); } else { sql_values[index] = document.getElementById(id).value; }
} else if (type == "checkbox") {
if (index == -1) { sql_values.push(document.getElementById(id).checked); } else { sql_values[index] = document.getElementById(id).checked; }
}
if (new_record == false) { sql_values.push(document.getElementById("student-id").value); }
}
async function deleteRecord() {
const { dialog } = require('electron').remote;
const options = {
type: 'question',
buttons: ['Yes', 'No'],
defaultId: 1,
title: 'Question',
message: 'Do you want to do this?',
}
var choice = dialog.showMessageBoxSync(null, options);
if (choice == 0) {
var sql = "DELETE FROM tblStudents WHERE idsStudentID = " + document.getElementById("student-id").value;
await pool.query(sql);
getData();
}
}
function firstRecord() {
saveRecord();
position = 0;
getData();
}
function previousRecord() {
saveRecord();
position--;
getData();
}
function nextRecord() {
saveRecord();
position++;
getData();
}
function lastRecord() {
saveRecord();
position = last_record;
getData();
}
async function newRecord() {
saveRecord();
const [rows, fields] = await pool.query('SELECT * FROM qryStudents');
new_record = true;
last_record = rows.length - 1;
position = last_record + 1;
console.log("NR: rows.length = " + rows.length + ", position = " + position + ", last_record = " + last_record);
refreshDataControl();
}
function refreshDataControl() {
console.log("RDC: last_record = " + last_record + ", position + 1 = " + (position + 1));
console.log("------------------------------------------------");
document.getElementById("record-number").value = position + 1;
if (position == 0) {
document.getElementById("first-record").disabled = true;
document.getElementById("previous-record").disabled = true;
document.getElementById("next-record").disabled = false;
document.getElementById("last-record").disabled = false;
} else if (position >= last_record) {
document.getElementById("first-record").disabled = false;
document.getElementById("previous-record").disabled = false;
document.getElementById("next-record").disabled = true;
document.getElementById("last-record").disabled = true;
} else {
document.getElementById("first-record").disabled = false;
document.getElementById("previous-record").disabled = false;
document.getElementById("next-record").disabled = false;
document.getElementById("last-record").disabled = false;
}
}
window.resizeTo(550, 700);
window.onload = getData();
</script>
调试输出显示前两次newRecord()
运行正常,随后五个实例rows.length
被错误报告,然后赶上最后一次运行。
[4151:0215/134309.258750:INFO:CONSOLE(300)] "RDC: last_record = 331, position + 1 = 333", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134309.258909:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134315.820950:INFO:CONSOLE(294)] "NR: rows.length = 333, position = 333, last_record = 332", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134315.821515:INFO:CONSOLE(300)] "RDC: last_record = 332, position + 1 = 334", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134315.822020:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134321.729763:INFO:CONSOLE(294)] "NR: rows.length = 333, position = 333, last_record = 332", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134321.729865:INFO:CONSOLE(300)] "RDC: last_record = 332, position + 1 = 334", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134321.729974:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134333.178796:INFO:CONSOLE(294)] "NR: rows.length = 334, position = 334, last_record = 333", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134333.178873:INFO:CONSOLE(300)] "RDC: last_record = 333, position + 1 = 335", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134333.178944:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134339.487472:INFO:CONSOLE(294)] "NR: rows.length = 335, position = 335, last_record = 334", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134339.488114:INFO:CONSOLE(300)] "RDC: last_record = 334, position + 1 = 336", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134339.488276:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134344.938782:INFO:CONSOLE(294)] "NR: rows.length = 336, position = 336, last_record = 335", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134344.939238:INFO:CONSOLE(300)] "RDC: last_record = 335, position + 1 = 337", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134344.939395:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134350.297774:INFO:CONSOLE(294)] "NR: rows.length = 337, position = 337, last_record = 336", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134350.297856:INFO:CONSOLE(300)] "RDC: last_record = 336, position + 1 = 338", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134350.297931:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)
[4151:0215/134355.734959:INFO:CONSOLE(294)] "NR: rows.length = 339, position = 339, last_record = 338", source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134355.735069:INFO:CONSOLE(300)] "RDC: last_record = 338, position + 1 = 340", source: file:///home/antioch/enrollmentdb/students-enrollments.html (300)
[4151:0215/134355.735468:INFO:CONSOLE(301)] "------------------------------------------------", source: file:///home/antioch/enrollmentdb/students-enrollments.html (301)```