【问题标题】:Q promise .then() undefinedQ 承诺 .then() 未定义
【发布时间】:2016-04-20 00:51:08
【问题描述】:

我正在尝试从 MySQL 数据库中异步提取数据,然后使用 Q Promise 处理结果(有史以来第一次尝试)。我正在使用here 列出的 Q defer() 函数。我创建了一个“包装器”对象,我最终将附加到 req.db 或通过来自 com.db 的循环依赖项(当前使用方式)进行访问,以允许在我的应用程序中使用 api。

Node 抛出指向 .then 回调的错误:

this.go().then(function(stuff){
                          ^
TypeError: Cannot call method 'then' of undefined

我尝试了以下方法:

var com = require('./mainRebuild');

function Base() {
    this.results = [];
    this.query = 'query here';
    this.go = function() {

        com.pool.getConnection(function(err, con) {

            if (err) throw err;
            /*
            THIS WORKS FINE (with callbacks)
             con.query('SELECT * FROM Users', function(err, rows){
                if (err) throw err;
                if (rows){

                  for (var i = 0; i < rows.length; i++){
                    this.results.push(rows[i]);
                    //console.log(rows[i]);
                  }
                }
                con.release();
                return this.results;
              }.bind(this));

              */
            var defer = com.Q.defer();
            con.query('SELECT * FROM Users', defer.makeNodeResolver());
            return defer.promise();
        }.bind(this));
    }
}

function DB() {
    this.getAllUsers = function() {
        this.query = 'SELECT * FROM Users';
        this.go().then(function(stuff) {
            console.log(stuff);
        }, function(err) {
            console.log(err);
        });
    }

}

DB.prototype = new Base();

module.exports = DB;

com 对象存在于主应用程序中,它包含所有常见的 require 模块。

我也试过了(好像错多了):

this.deffered = com.Q.defer();
com.pool.getConnection(function(err, con) {

            if (err) this.deferred.reject(new Error(err));

            con.query('SELECT * FROM Users', function(err, rows) {
                if (err) throw err;
                if (rows) {
                    this.deferred.resolve(rows);
                }
                con.release();
                return this.deferred.promise.done;
            }.bind(this));

            com.Q.nfcall(this.go()).then...

我找到了几篇关于将 Q 适配到节点的文章,例如 this。

【问题讨论】:

  • this.go 不返回任何内容...
  • 我想我只是对我正在尝试编写的嵌套延迟函数感到困惑。你能解释一下如何让 this.go 返回嵌套的 deferred 吗?
  • 在go 中创建承诺,而不是在回调中。这是一个简化的示例:function foo() { function bar() { return 42; }; bar(); }。你期待foo()真的返回42吗?
  • return defer.promise(); 应该是return defer.promise;
  • 是的,将 defer 放在回调之外,然后在 foo 中返回,效果很好。还有defer.promise。有人请写下答案,我会接受的!谢谢大家!

标签: javascript node.js q


【解决方案1】:

应该这样做(“应该”,因为我无法用 MySQL 测试它)

var Q = require('Q');

function DB(pool) {
    this.asyncQuery = function(sql) {
        return function () { 
            var result = Q.defer(),
                paramsArray = [].slice.call(arguments);
            pool.getConnection(function(err, con) {
                if (err) return result.thenReject(err);
                con.query(sql, paramsArray, result.makeNodeResolver());
                result.promise.finally(function () {
                    con.release();
                });
            });
            return result.promise;
        };
    };
    this.getAllUsers = this.asyncQuery('SELECT * FROM Users');
    this.getUserByName = this.asyncQuery('SELECT * FROM Users WHERE name = ?');
}

module.exports = DB;

用法:

var DB = require('./DB');
var com = require('./mainRebuild');
var db = new DB(com.pool);

db.getAllUsers().then(function (users) {
    console.log(users);
});

db.getUserByName('JohnDoe').then(function (user) {
    console.log(user);
});

var customQuery = db.asyncQuery('SELECT * FROM foo WHERE id = ?');
customQuery(42).then(function (result) {
    console.log(result);
});

【讨论】:

  • 漂亮。将工厂函数添加到 module.exports 返回 new DB() 允许导出的对象完全可链接。 :D 例如module.exports = createApp; function createApp() { return new DB(); }
  • 另见修改后的答案。 DB的定义不需要知道pool是在'./mainRebuild'中定义的。我们可以注入它。
  • 是否有理由不从 './mainRebuild' 导入依赖项?注射更可取,它如何优越?
  • 嗯,使用哪个连接与您的数据库适配器无关。您可以(理论上)拥有多个数据库或连接池,将池传递给 DB 构造函数允许这种模式。
  • 很抱歉挖掘了那个线程,但我喜欢你模块化代码的方式,但是这样,连接不会被释放。是不是很危险?
猜你喜欢
  • 2021-10-24
  • 2015-08-15
  • 1970-01-01
  • 2018-08-17
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多