【问题标题】:jQuery executes codeparts in the wrong orderjQuery 以错误的顺序执行代码部分
【发布时间】:2021-05-17 01:55:27
【问题描述】:

我目前正在为我的叔叔做一个项目,他是一名兽医。这是一个电子项目,让他可以管理他的客户、病人和他们的访问。然而,在使用一段时间后,我们意识到,有时 ipcRenderer 在尝试插入新客户、患者或约会时会触发两次,甚至更多次。我试图通过添加另一个 sql 查询来捕获这一点,该查询检查是否有相同的记录,我想要插入的内容已经在数据库中。但是现在,每当我尝试插入新记录时, db.all() (起初是 db.run() ,在过去的几个小时里,我一直在尝试通过反复试验来修复并且绝望了)哪个插入记录在 db.all() 之前执行,它获取相同记录的数量并设置计数器,尽管它应该在之后执行。我尝试使用 $.when() 和 .done() 来解决这个问题,但是遇到了无法检查计数器是否为 0 的问题,因为 .done() 需要一个函数,而 .done(如果) 不起作用。顺便说一句,我更像是一个 C++、java、C# 的家伙,并且对 jQuery、JS 和其他东西不太熟悉,如果我的错误是微不足道的,那么抱歉。 这是代码,你可以忽略这些长的 SQL 语句,我知道,它们不符合编码约定,但它们有效:

$("#btn-ins-patient").on("click", function() {
        ipcRenderer.once('insert-patient', function(event, arg) {
                        
            let checksql = "select count(*) as 'zaehl' from patient where "
            + "owner = " + arg.owner + " and name = '" + arg.name + "' and species = '" + arg.species + "' and breed = '" + arg.breed + "' and sex = '" + arg.sex + "' and neutered = '" + arg.neutered + "' and dead = '" + arg.dead + "' and chipnr = '" + arg.chipnr + "' and birthdate = '" + arg.birthdate + "'  and color = '" + arg.color + "';"

            db.all(checksql, function(error, rows) {
                if (error) {
                    console.log(error.code, checksql)
                    insertpatsql = "select * from patient where id = 1;";
                }
                else{
                    console.log(checksql);                      //second output in console, prints the right statement
                    for (let i = 0; i < rows.length; i++) {
                        var counter = rows[i].zaehl;
                        console.log(counter);                   //third output in console, prints 0
                        setCount(counter);
                        console.log(cnter);                     //fourth output in console, prints 0 again
                    }
                    if(cnter != 0){
                        insertpatsql = "select * from patient where id = 1;";
                        console.log(insertpatsql);
                        console.log("double entry was stopped");
                    }
                    else{
                        
                        console.log(insertpatsql);              // fifth output in console prints the right statement (insert)

                    }
                    
                }  
            });

            let insertpatsql = "insert into patient"
            + "(owner, name, species, breed, sex, neutered, dead, chipnr, birthdate, color, notes, diverse)"
            + "values ('" + arg.owner + "', '" + arg.name + "', '" + arg.species + "', '" + arg.breed + "', '" + arg.sex + "', '" + arg.neutered + "', '" + arg.dead + "', '" + arg.chipnr + "', '" + arg.birthdate + "', '" + arg.color + "', '" + arg.notes + "', '" + arg.diverse + "');";

            if(cnter == 0){
                db.all(insertpatsql, function(error) {
                    if (error) {
                        console.log(error.code, insertpatsql)
                    }
                    else{
                        console.log(insertpatsql);
                        loadPatients();
                    }
                });
            }
            else{
                console.log("double entry was tried", insertpatsql, cnter);
                                                              //first output in console, cnter is undefined
            }
        })

        let child = new BrowserWindow({
            height: 485,
            width: 795,
            parent: parent,
            modal: true,
            resizable: false,
            show: false,
            webPreferences: {
                nodeIntegration: true
            }
        })

        child.loadFile('./ins/patient.html')

        child.once('ready-to-show', () => {
            child.show()
        })

        child.on('closed', () => {
            child = null
        })
    })

select * from patient where id = 1; 只是出于安全原因,因为有时会执行第二个 db.all(),即使它不应该执行。我知道我的代码很乱,对不起,我整天都在努力解决这个问题......

这就是我设置 cnter(全局变量)的方式:

var cnter;

function setCount(cnt){
    cnter = cnt;
}

如何确保 checksql 及其代码块在插入之前执行?

【问题讨论】:

  • 你的意思是第一个请求没有完成,第二个请求开始了?
  • 基本上是的。我不明白这是如何或为什么会发生的。第一个 db.all() 和 if(cnter == 0) 必须几乎同时启动。为什么在开始另一个块之前它不能在第一个块中全部工作?还是一开始就开始第二个?
  • db.all 不是异步的?

标签: javascript jquery sqlite electron


【解决方案1】:

好的,我想我解决了这个问题,将第二个块放在第一个块中。这是现在的代码:

$("#btn-ins-patient").on("click", function() {
        ipcRenderer.once('insert-patient', function(event, arg) {
                        
            let checksql = "select count(*) as 'zaehl' from patient where "
            + "owner = " + arg.owner + " and name = '" + arg.name + "' and species = '" + arg.species + "' and breed = '" + arg.breed + "' and sex = '" + arg.sex + "' and neutered = '" + arg.neutered + "' and dead = '" + arg.dead + "' and chipnr = '" + arg.chipnr + "' and birthdate = '" + arg.birthdate + "'  and color = '" + arg.color + "';"

            let insertpatsql = "insert into patient"
            + "(owner, name, species, breed, sex, neutered, dead, chipnr, birthdate, color, notes, diverse)"
            + "values ('" + arg.owner + "', '" + arg.name + "', '" + arg.species + "', '" + arg.breed + "', '" + arg.sex + "', '" + arg.neutered + "', '" + arg.dead + "', '" + arg.chipnr + "', '" + arg.birthdate + "', '" + arg.color + "', '" + arg.notes + "', '" + arg.diverse + "');";


            db.all(checksql, function(error, rows) {
                if (error) {
                    console.log(error.code, checksql)
                    insertpatsql = "select * from patient where id = 1;";
                }
                else{
                    console.log(checksql); //first output in console
                    for (let i = 0; i < rows.length; i++) {
                        var counter = rows[i].zaehl;
                        console.log(counter); //second output in console
                        setCount(counter);
                        console.log(cnter); //third output in console
                    }
                    if(cnter != 0){
                        insertpatsql = "select * from patient where id = 1;";
                        console.log(insertpatsql);
                        console.log("double entry was stopped");
                    }
                    else{
                        
                        if(cnter == 0){
                            db.all(insertpatsql, function(error) {
                                if (error) {
                                    console.log(error.code, insertpatsql)
                                }
                                else{
                                    console.log(insertpatsql);
                                    loadPatients();
                                }
                            });
                        }
                        else{
                            console.log("double entry was tried", insertpatsql, cnter); //fourth output in console, cnter is undefinded
                        }

                    }
                    
                }  
            });
            
        })
})

我不知道它是否真的有效,直到 ipcRenderer 尝试再次触发两次。一旦我确认它有效,我会标记它。

【讨论】:

    【解决方案2】:

    我不明白!!,但这是链接数据库事务的架构

    function onSomeButtonClick()
    {
      // The first query callback
      var firstQueryResults;
      var firstQuery = function(tx) {
        tx.executeSql(
          'SELECT * FROM databaseName WHERE greeting = "hello world"',
          [],
          function(tx, results) {
            firstQueryResults = results;
            return nextQuery(tx);
          });
      };
    
      var nextQuery = function(tx) {
        // Prepare something using firstQueryResults
        tx.executeSql('SOMETHING ELSE HERE',
          [],
          function(tx, results) {
            // Something good happens here
            return true; // Be sure to return false to roll back
          });
      };
    
      database.transaction(firstQuery, null, nextTransaction);
    }
    
    function nextTransaction() {
      // The next full transaction that's dependent on the
      // first transaction's data is called AFTER the first
      // transaction has completed.
    }
    

    【讨论】:

    • 感谢您的回答!我收到了警报,但除此之外,其他一切都保持不变。对不起,如果我的问题措辞奇怪,我会尝试总结问题:有时当我尝试插入一条记录时,这条记录会被插入两次。我环顾四周,发现这与 ipcRenderer 多次执行有关。我试图用 checksql 来解决这个问题,但是现在,第二个 db.all() 在第一个块完成之前执行,这使得第一个基本上没用,因为代码依赖于 checksql 在插入之前填充 cinter .
    • 警报不会结束进程,所以你可以初始化一个 setInterval 来等待 checksql 的正确值
    • 我读到 db.all 是异步的,所以你可以使用 .then() 来执行下一个动作
    【解决方案3】:

    我怀疑问题在于您在事件处理程序中注册了一个事件处理程序。在大多数情况下,事件处理程序应该在全局范围内注册一次,而不是在另一个事件处理程序中。

    我不了解您使用该计数器所做的所有事情,但我认为您正在尝试这样做:

    ipcRenderer.on('insert-patient', function(event, arg) {
                    
        let insertpatsql = "insert into patient"
        + "(owner, name, species, breed, sex, neutered, dead, chipnr, birthdate, color, notes, diverse)"
        + "values ('" + arg.owner + "', '" + arg.name + "', '" + arg.species + "', '" + arg.breed + "', '" + arg.sex + "', '" + arg.neutered + "', '" + arg.dead + "', '" + arg.chipnr + "', '" + arg.birthdate + "', '" + arg.color + "', '" + arg.notes + "', '" + arg.diverse + "');";
    
        db.all(insertpatsql, function(error) {
            if (error) {
                console.log(error.code, insertpatsql)
            }
            else{
                console.log(insertpatsql);
                loadPatients();
            }
        });
    })
    
    $("#btn-ins-patient").on("click", function() {
    
        let child = new BrowserWindow({
            height: 485,
            width: 795,
            parent: parent,
            modal: true,
            resizable: false,
            show: false,
            webPreferences: {
                nodeIntegration: true
            }
        })
    
        child.loadFile('./ins/patient.html')
    
        child.once('ready-to-show', () => {
            child.show()
        })
    
        child.on('closed', () => {
            child = null
        })
    })
    

    【讨论】:

    • 感谢您的建议!我知道计数器有点令人困惑,但我必须将其定义为全局变量并创建一个集合函数,否则我将无法在第二个范围内访问它。我曾一度将它放在函数内部,但后来它没有设置它,所以我将它设为全局。事后看来,这可能是因为代码块以错误的顺序执行,所以我明白为什么会令人困惑。总的来说,我也不是最擅长编码的人,并且在尝试不同方法时往往不会逆转我在寻找错误时所做的不必要的编辑......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多