我对Node比较陌生,但我在移植以前在PHP中完成的RESTful API方面取得了很大的成功。有相当多的数据库交互,因此我发现自己进入了我认为很多人称之为“厄运金字塔”的#34;由于Node的异步性质。
因此,我正在尝试使用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 :(得分: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 = ?');
我认为使用.then(function ...)没有任何好处,因为它仍然需要像回调那样嵌套。
除了更简单的错误处理之外,好处来自于链接多个任务,即您的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();
});
}