数组长度报告不一致

问题描述

我十年前开发了一个 MS Access 桌面数据库应用程序,现在我正在尝试使用 node、electron 和 MysqL 进行重建,因为我是一个正在恢复的 Windows 用户

在导入数据库的必要部分后,我首先在应用程序中重新创建最简单的表单:https://imgur.com/a/oRfcsXw

问题在于数据控件的操作(左下),特别是在使用新记录按钮(“>+”)时。虽然它有时会正确增加记录编号(屏幕截图中的“336”),但有时不会。当它粘住时,继续添加记录最终会使其在最终再次粘住之前突然赶上。调试表明原因是未正确报告 rows.length 中的 newRecord()

可以肯定地假设这与我令人沮丧地无法解释无法完全理解异步执行、回调、promise 和 async/await 相关,尽管在过去四天里我的头脑中等并且与无数关于该主题文章发生冲突。我想在我能够更好地掌握这个概念之前,我只需要看看一个如何做到这一点的例子,因为它适用于我的情况。所以请随意忽略下面这个菜鸟代码中的许多缺陷,其中一些他知道,我确定其中很多他没有,只关注我如何获得准确的 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,source: file:///home/antioch/enrollmentdb/students-enrollments.html (294)
[4151:0215/134321.729865:INFO:CONSOLE(300)] "RDC: last_record = 332,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)```

解决方法

答案似乎就像在 await 中将 saveRecord() 放在 newRecord() 前面一样简单。

新的和改进的newRecord()

        async function newRecord() {
            await saveRecord();

            const [rows,fields] = await pool.query('SELECT * FROM qryStudents');
            new_record = true;
            last_record = rows.length - 1;
            position = last_record + 1;
            refreshDataControl();
        }