简体   繁体   English

节点MySQL-承诺永无止境

[英]Node MySQL- Promise Never Ends

I'm having an issue with promises in node, specifically in the following code, which I wrote to execute a MySQL query so all my other 100+ functions can share this instead of writing it inline. 我在诺言中遇到了一个问题,特别是在以下代码中,我编写了该代码来执行MySQL查询,以便我的所有其他100多个函数可以共享此函数,而不必内联编写。 Coming from PHP development, it's been a learning curve to understand the benefits of promises and whatnot, and now I have hit a bit of a problem. 来自PHP开发,了解promise和其他方面的好处是一个学习的过程,现在我遇到了一些问题。 Here is the function that takes query as a parameter, executes it, and returns the response: 这是将query作为参数,执行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();
                });

            });

        });


    }
}

The code runs fine and the value gets returned to the caller, but it just doesn't seem to terminate, regardless of what I try and I'm concerned it's eating CPU resource. 该代码运行良好,并且该值已返回给调用者,但无论我尝试执行什么,而且它正在消耗CPU资源,它似乎都没有终止。

Here is an example function you can run to use with the function above in command line, to see what is happening. 这是一个示例函数,您可以在命令行中将其与上述函数一起使用,以查看发生了什么。

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);
});

}

Questions: 问题:
- is it necessary for the promise to terminate? -诺言是否有必要终止?
- Is there a mistake in my code? -我的代码有错误吗?
- Is there a better way to make a reusable database execution function like I have? -是否有更好的方法来使可重用的数据库执行功能像我一样?

UPDATE - I have also tried an alternative method using Bluebird to "promisify" the mysql library. 更新 -我还尝试了使用Bluebird来“承诺” mysql库的替代方法。 The function still never ends and I have to CTRL+C in my terminal to quit it. 该功能仍然永无止境,我必须在终端中按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")
                 }
            });
    }

}

I found the solution that fixes my issue. 我找到了解决我的问题的解决方案。

Using connection.destroy() allows the functions to properly end, so they no longer cause the "hanging". 使用connection.destroy()可使函数正确结束,因此它们不再导致“挂起”。

The two sets of code I posted in my original post do work, so it might help someone else in future. 我在原始帖子中发布的两套代码可以正常工作,因此将来可能会对其他人有所帮助。

You should call resolve('some data to return'); 您应该调用resolve('一些要返回的数据'); when all operations and you release the mysql descriptor. 当所有操作完成后,您释放mysql描述符。 Try to change it to 尝试将其更改为

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

is it necessary for the promise to terminate? 诺言有必要终止吗?

Promise is not terminating. 承诺不会终止。 Promise has three states: Running, Rejected, Resolved. Promise具有三个状态:运行,已拒绝,已解决。 So .then() chain won't be called if your previous promise is still executing. 因此,如果您先前的承诺仍在执行,则不会调用.then()链。 So yes, you MUST set appropriate state for your promise: resolved or rejected in order to call next chained operations. 因此,是的,您必须为诺言设置适当的状态:已解决或已拒绝,以便调用下一个链接的操作。

Is there a mistake in my code? 我的代码有错误吗?

Yes you definetely mistaken in usage of return statement. 是的,您肯定在使用return语句时犯了错误。 Be aware that as soon as you called return , your function is terminated and code after return statement won't be executed 请注意,一旦调用return ,函数就会终止,并且return语句后的代码将不会执行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM