节点MySQL-承诺永远不会结束

时间:2017-02-20 17:26:32

标签: javascript mysql node.js promise

我在节点中遇到了promises的问题,特别是在下面的代码中,我编写了这些代码来执行MySQL查询,所以我所有的其他100多个函数都可以共享它而不是内联编写它。来自PHP开发,了解promises和whatnot的好处是一个学习曲线,现在我遇到了一些问题。以下是将query作为参数,执行并返回响应的函数:

var mysql = require('mysql');
const myDBConnection = mysql.createPool({
    host: '127.0.0.1',
    user: "username",
    password: "password",
    database: "dbName",
    connectionLimit: 101,
});


class DBQueryRunner {
    query(query) {
        return new Promise((resolve, reject) => {
            myDBConnection.getConnection((err, connection) => {


                const myQuery = mysql.format(query.string, query.params);
                connection.query(myQuery, function(err, data) {
                    return (err ? reject(err) : resolve(data));
                    connection.release();
                });

            });

        });


    }
}

代码运行正常并且值返回给调用者,但它似乎没有终止,无论我尝试什么,我担心它正在占用CPU资源。

这是一个示例函数,您可以在命令行中使用上述函数来查看正在发生的事情。

function test() {
let DBQueryRunner = require("./theAboveCode.js");
const myDB = new DBQueryRunner();

let query = {
    string: `SELECT 1+1 AS Output`,
    params: []
};


return myDB.query(query).then(rows => {
console.log(rows)
    return (rows);
});

}

问题:
- 承诺是否有必要终止? - 我的代码中有错误吗?
- 有没有更好的方法来制作像我一样的可重用数据库执行功能?

UPDATE - 我还尝试了一种使用Bluebird来“宣传”mysql库的替代方法。该功能仍然永远不会结束,我必须在我的终端中按CTRL + C才能退出它。

let mysql = require('mysql');
let Promise = require('bluebird');

Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);


let myDBConnection = mysql.createPool({
  host: '127.0.0.1',
  user: "username",
  password: "password",
  myDBConnection: "dbName",
  connectionLimit: 101,
});




class DBQueryRunner {
  query(query) {
    let pool = Promise.promisifyAll(mysql);

        return myDBConnection.getConnectionAsync()
            .then(function (conn) {
                 myDBConnection = Promise.promisifyAll(conn);
                 return myDBConnection.queryAsync(query.string, query.params);
            })
            .then(function (results) {
                 if (results.length < 1) {
                     return "No results were found";
                 } else {
                     return results;
                    //  resolve(results);  //This method doesn't work with resolve/reject so I already am confused by it.
                 }
            })
            .catch(function (err) {
                 console.log(err);
                 throw err;
            })
            .finally(function () {
                 if (myDBConnection) {
                     myDBConnection.release();
                     console.log("Released the connection")
                 }
            });
    }

}

2 个答案:

答案 0 :(得分:2)

我找到了解决问题的解决方案。

使用connection.destroy()可以让函数正常结束,因此它们不再导致&#34;挂起&#34;。

我在原帖中发布的两组代码可以正常运行,因此将来可能对其他人有所帮助。

答案 1 :(得分:0)

你应该调用resolve('返回一些数据');当所有操作和你释放mysql描述符时。尝试将其更改为

connection.release(); 
return (err ? reject(err) : resolve(data)); // The return operator will EXIT from function before connection released. Maybe this is what causes the problem
  

承诺是否有必要终止?

承诺不会终止。 Promise有三种状态:Running,Rejected,Resolved。因此,如果您的先前承诺仍在执行,则不会调用.then()链。所以,是的,您必须为您的承诺设置适当的状态:已解决或拒绝,以便调用下一个链式操作。

  

我的代码中有错误吗?

是的,你定义错误地使用return语句。请注意,只要您调用返回,您的功能就会终止,并且返回语句后的代码将无法执行