2014-01-22 50 views
3

我对Node相对来说比较新,但是在通过先前在PHP中完成的RESTful API移植方面取得了很好的成功。有很多数据库交互,因此我发现自己陷入了我认为由于Node的异步性质,许多人称之为厄运的金字塔。在Node-Mysql中使用Q

因此,我尝试使用Q库实现承诺,但是我还没有获得太多成功,并且当我相信我应该获取数据时,仍然收到空结果集。下面是我添加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()的电话中包含什么,但我尝试了很多事情,但都没有成功。

+0

即使没有承诺,一个'getRow'可能永远不会调用它的'callback'是一个坏主意。至少做一个'回调(nothingFoundError)' – Bergi

+0

你能否也请告诉我们你使用承诺的方法? – Bergi

+0

@Bergi已添加。我知道的非常粗糙,但这是我经过几轮试验和错误后所剩下的一切。 –

回答

4

getRow承诺的功能看起来很有希望:-)它可以通过使用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 = ?'); 

我看不出使用。那么(函数任何好处.. ),因为它仍然需要嵌套,就像回调一样。

的好处(除了容易错误处理)来自链接多个任务,即当你还和security.verifyToken方法helper.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(); 
    }); 
}