node.js + mysql: «Невозможно поставить в очередь рукопожатие после того, как оно уже было включено в рукопожатие». - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь создать две функции, одна из которых получает объект из базы данных SQL, а другая сохраняет объект в той же базе данных SQL.Я использую node.js и mysql, чтобы сделать это.У меня есть две функции fetchEmployee и Employee.save, которые выбирают и сохраняют сотрудника соответственно.Когда я звоню fetchEmployee, а обратный вызов включает Employee.save, я получаю ошибку Cannot enqueue Handshake after already enqueuing a Handshake. Еще более странно, Employee.save, кажется, запускается до того, как выдается ошибка.1012 *: employee.save появление для запуска является признаком асинхронности, так как console.log("Saved!") вызывается до того, как функция обратного вызова передана в SQL.parse Это означает, что ошибка появляется во время parse.Кроме того, если в течение синтаксического анализа console.log("connection created"); добавляется после con.connect, а console.log("Made it out."); добавляется после окончания con.connect, при вызове Employee.save консоль выводит > "connection created", а затем выдает ошибку, что означает сохранениезапрос никогда не завершается, но ошибка выдается после con.connect

Класс Employee определяется следующим

function Employee(obj) {
    /** Defines the Employee class
     * @arg obj.id : an integer; the employee's id
     * @arg obj.name : A string; the employee's name
     * @arg obj.position : A string; the employee's positions split by commas
     */

    this.id = obj.id;
    this.name = obj.name;
    this.position = obj.position;

    this.save = function() {
        SQL.parse({
            sql : `UPDATE EMPLOYEES
                SET id=?, name=?, position=?
                WHERE id=?`,
                replace_ : [this.id, this.name, this.position, this.id],
                result : false
        });
        console.log("Saved!");
    }
}

Обратите внимание на console.log("Saved!");, так как это появится позже

fetchEmployee определяется этой функцией:

function fetchEmployee(id, callback) {
    /** Fetch an employee from the employee table
     * @arg id : An integer; the id of the employee to fetch
     * @arg callback : A callback function to pass the employee to
     */

     SQL.parse({ // Perform the parse, define the sql, replace, and result
        sql : "SELECT * FROM employees WHERE id=?",
        replace_ : [id],
        result : true
     },

     function(err, data) {
         if(err) { // Pass an error if there's an error
             callback(err, null);
             throw err;
         }
         // Pass the employee to the callback as an employee object if there's no errors
         callback(null, new Employee({  // data is passed as a list from the sql table, so take only the object we need through [0]
                id : data[0].id,
                name : data[0].name,
                position : data[0].position
             })
         );
     });
}

Наконец, SQL.parse определяется в этом файле:

var mySQL = require("mysql");

var con = mySQL.createConnection({ //Create connection
    host : "localhost",
    database : "testdb1",
    user : "root",
    password : "***************" 
});

function parse(obj, callback) {
    /** Parses an sql query. 
     * @arg callback : A callback function, will be passed the data
     * @arg obj.sql : an sql query
     * @arg obj.replace_ : A list of replacements for ?s in sql
     * @arg obj.result : a boolean indicating whether a result should be returned
     */

     //Assign meaningfull values
     obj.replace_ = obj.replace_ || [];
     callback = callback || function() {};

    con.connect(function(err) {
        if(err) throw err;

        //Connect and pass the sql command to the server
        con.query(obj.sql, obj.replace_, function(err, data) {
            if(err) { //Pass the err to the callback if there is an err
                callback(err, null);
                throw err;
            }
            else if(obj.result) { // Pass the data to the callback if result is true
                callback(null, data)
            }
        });
    });
}

module.exports = {
    parse : parse
};

Когда я вызываю этот блок кода

fetchEmployee(985, function(err, data) {
    if(err) throw err;
    console.log(data);
    data.save();
});

Консоль выводит

Employee {
  id: 985,
  name: 'Skidd',
  position: 'Dishwasher, Busser',
  save: [Function] }
Saved!
Error: Cannot enqueue Handshake after already enqueuing a Handshake. [...]

Мне кажется, что она правильно работает fetchEmployee, поскольку данные регистрируются на консоли правильно с данными сотрудника.Затем он регистрирует Saved!, по-видимому, показывая, что Employee.save работает правильно, а затем, после того как весь код выполнен, выдает ошибку.Я не могу понять, почему это произойдет, здесь, в Google или с помощью тестирования.

Я пытался добавить con.end к концу parse в sql.js, это изменяет ошибку на Cannot enqueue Handshake after invoking quit

1 Ответ

0 голосов
/ 24 октября 2018

Мне удалось решить эту проблему, поместив

var con = mySQL.createConnection({ //Create connection
    host : "localhost",
    database : "testdb1",
    user : "root",
    password : "***************" 
});

внутри функции parse, хотя я не уверен на 100%, почему это сработало.

...