【问题标题】:Node, Bluebird Promises, MySQL, and the need for a stiff drinkNode、Bluebird Promises、MySQL,以及对烈酒的需求
【发布时间】:2026-01-24 17:35:01
【问题描述】:

我正在努力用 MySql 实现 Bluebird 的承诺。我想我已经接近了,但我的问题开始复杂化,我可以使用一些帮助回到正轨。我让这段代码都使用回调,但我已经用 Promise 提升了它。

目前的问题是它不喜欢我查询中的“then”,如:

conn.query("DO DB STUFF").then(function(result){});

首先,我有一个如下所示的 connection.js 文件。我在代码中添加了一些 cmets。

(function () {
var mysql = require("mysql");

var pool = mysql.createPool({
    connectionLimit: 10,
    host: "localhost",
    user: "myuser",
    password: "password",
    database: "dbName"
});

// stole this from http://*.com/questions/24797314/how-will-a-promisified-mysql-module-work-with-nodejs
exports.getConnection = function(){
    return pool.getConnectionAsync().disposer(function(connection){
        try{
            connection.release();
        } catch (e) {}
    });
};
})();

然后我有一个看起来像这样的“db access”文件:

var Promise = require("bluebird");
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
var connection = require("./connection");
var common = require("../../domain/common");

exports.isKnownBadTicker = function (stockSymbol) {
    if (stockSymbol == null) { return false; }
    else {
        var ticker = common.standardizeStockSymbol(stockSymbol);
        var query = "SELECT COUNT(*) AS count FROM BadTicker WHERE Symbol = '" + ticker + "';";
        // it doesn't like the conn.query(query).then . . . says that "then" is not valid, and so I tried to just return the response of the query - which also doesn't work.
        Promise.using(connection.getConnection(), function (conn) {
            return conn.query(query)[0]["count"] > 0;
            // conn.query(query).then(function (result) {
            //  return result[0]["count"] > 0;
            // });
        });
    }
};

我觉得我已经很接近了,但我就是不能把它放在一起。谁能帮我解决这个问题?

另外,我不确定我是否做对了其他一些事情,例如,我可以在一个也返回 Promise 的函数中返回一个布尔值吗?如果您发现我已经变得很古怪,请随时纠正我。任何帮助表示赞赏。

维克

【问题讨论】:

  • 您认为Promise.promisifyAll(require("mysql/lib/Connection").prototype); 完成了什么?您没有保存 require() 操作的任何返回值,所以我想知道您认为此操作的结果是什么?
  • 从这里获取代码:github.com/petkaantonov/bluebird/blob/master/…。显然,这并不意味着我使用正确。

标签: javascript mysql node.js bluebird


【解决方案1】:

当你使用promisifyAll 异步函数时,它们会得到带有Async 后缀的兄弟。所以你必须使用queryAsync 而不是query

conn.queryAsync("DO DB STUFF")
  .then(function(result){
    // dont forget here that result is an array
  });

在第二个连接示例中承诺是可以的(我的版本更丑)

var Promise = require('bluebird');
var mysql = require('mysql');
Promise.promisifyAll(mysql.Connection.prototype);
Promise.promisifyAll(require('mysql/lib/pool').prototype);

mysql 模块中获取连接是同步的,而不是异步的。我认为这样做是为了简化,但现在它使事情变得更加混乱。因此,当您调用 mysql.createPool 时,您不必等待,并且可以立即使用返回的 pool - mysql 模块将存储您的查询并在真正建立连接时执行它。

/* store this pool in a good place - you have to reuse it. */
var pool = mysql.createPool(credentials); 
/* you could also create connection like this 
   var conn = mysql.createConnection(credentials);
   , but pull is better when you want to do many queries at a time */

现在您可以像这样使用pool 进行承诺查询

pool.queryAsync("DO DB STUFF")
  .then(function(result){
    // dont forget here that result is an array
  }); 

【讨论】:

    【解决方案2】:

    我也想不通! 我得到的最接近的是:

    var Promise = require("bluebird");    
    var mysql = require("mysql");
    var pool = mysql.createPool({
     connectionLimit: 10,
     host: "localhost",
     user: "myuser",
     password: "password",
     database: "dbName" });
    pool.query = Promise.promisify(pool.query);
    pool.query("DO DB STUFF")
      .spread(function(rows,fields){
        //access your rows here
        });
    

    问题是字段被附加到行数组中,因此您需要使用 .spread。

    然而,这整件事让我很不舒服,因为我不知道如何使用它,所以我查看了 knex,它只是一个查询构建器,并且原生支持 Promise。

    【讨论】: