将 Q 与 Node-Mysql 一起使用

Posted

技术标签:

【中文标题】将 Q 与 Node-Mysql 一起使用【英文标题】:Using Q with Node-Mysql 【发布时间】:2014-02-13 00:07:43 【问题描述】:

我对 Node 比较陌生,但我在移植 RESTful API 方面取得了很好的成功,而这之前是在 php 中完成的。由于 Node 的异步特性,我发现自己陷入了许多人所说的“末日金字塔”中。

因此,我正在尝试使用 Q 库实现 Promise,但我还没有取得太大的成功,当我认为我应该获取数据时,我仍然得到空结果集。下面是我在添加 Q 之前的当前结构,如果有人可以建议如何为此正确实现 Q,我将能够使用该示例运行并将其余的数据库/memcached 调用转换为该模型。

// helper function to get a company row
getRow = function(lookUp, callback) 
    var query = db.query('SELECT * FROM table WHERE lookUp = ?', lookUp, function(err, result) 
        var count = Object.keys(result).length;

        if(count == 0) 
            return;
         else 
            callback(null, result);
        
    );


// function that uses the above helper method
insertItem = function(request, response) 
    var data = JSON.parse(request.body.data);
    var message = data.message;
    var lookUp = data.lookUp;

    security.verifyToken(lookUp, function (lookUpError) 
        if (lookUpError) 
            var errorResult =  "response": "error", "msg": lookUpError ;
            response.json(errorResult);
            response.end();
         else 
            getRow(lookUp, function (companyError, row) 
                var companyId = row[0].id;

                var res = helper.insertFeedItem(companyId, message, function (insertError, insertResult) 
                    var result = (feedError) ?  "response": "error", "msg": insertError : insertResult;
                    response.json(result);
                    response.end();
                );
            );
        
    );

我想要完成的是能够做类似的事情:

var result = getCompanyRow(lookUp);
companyId = result.company_id;

同样,对于如何最好地实现 Q(或一般来说只是承诺)的任何见解将非常感谢。

* 编辑:

这是我迄今为止为实现 Q 所做的尝试,但正如我所说,我没有得到任何回报。

function getRow(id) 
  var dfd = Q.defer();
  var query = db.query('SELECT * FROM table WHERE lookUp = ?', id, function(err, result) 
    if(err)  dfd.reject(err); 
    else  dfd.resolve(result); 
  );
  return dfd.promise;

上述方法在调用时根本不起作用 result = getRow(id);我尝试使用 Q.all 并将函数绑定到该函数,但在尝试这种方法时我也没有得到任何回报。我不确定在调用 .then() 时要包含什么内容,但我尝试了很多方法,但都没有成功。

【问题讨论】:

一个 getRow 可能永远不会调用它的 callback 是一个坏主意,即使没有承诺。至少做一个callback(nothingFoundError) 能否请您也向我们展示一下您使用 Promise 的方法? @Bergi 添加。我知道非常粗略,但经过几轮反复试验后,我只剩下这些了。 getRow 函数看起来相当不错 - result 将是 promise 对象。 insertItem你是怎么用的? 是的,result 是您可以调用.then() 方法的promise 对象。 then 接受的回调将被赋予你 resolve()d 你的延迟对象。 【参考方案1】:

您的getRow promise 函数看起来很有希望 :-) 可以使用 node adapter methods from Q 进一步简化它:

function getRow(id) 
    return Q.nfcall(db.query,    'SELECT * FROM table WHERE lookUp = ?', id);
    //      ^^^^^^^^^^^^^^^^^^^^
    // or   .ninvoke(db, "query", … if it must be called as a method

// or even just
var getRow = Q.nbind(db.query, db, 'SELECT * FROM table WHERE lookUp = ?');

我认为使用 .then(function ...) 没有任何好处,因为它仍然需要嵌套,就像回调一样。

好处(除了更容易的错误处理)来自链接多个任务,即当您的 security.verifyTokenhelper.insertFeedItem 方法也将返回承诺时。如果它们没有(并且您不能修改它们),您仍然可以使用Q.nfcall,如上例所示。假设他们这样做了,您的代码可以简化为

function insertItem(request, response) 
    var data = JSON.parse(request.body.data);

    security.verifyToken(data.lookUp).then(function(/* no lookupError */) 
        return getRow(data.lookUp); // potentially catch SQL errors here
    ).then(function(row) 
        return helper.insertFeedItem(row[0].id, data.message);
        // What was the `res` it had returned before?
    ).catch(function(someError)  // lookUpError, companyError, insertError
        return  "response": "error", "msg": someError ;
    ).done(function(result) 
        response.json(result);
        response.end();
    );

【讨论】:

以上是关于将 Q 与 Node-Mysql 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

INSERT INTO 因 node-mysql 失败 - 变量始终为 NULL

Nodejs与MySQL交互(felixge/node-mysql)

如何将 django 的 Q 与 django taggit 一起使用?

我们可以将 Q_PROPERTY 与 template<typename T> 一起使用吗?

在 node-mysql 中使用 SSH 隧道连接到 MySQL

Elasticsearch/Nest - 将 MatchPhrase 与 OnFieldsWithBoost 一起使用