我正在使用the 'Q' library作为承诺。
以下是该方案:
var results = dbContext.query(userCert.conn, dbQuery.BuildQuery(query));
var models = [];
if (!results.hasErr) {
for (var r in results.okPacket.results) {
var m = new model(results.okPacket.results[r]);
models.push(m);
}
}
userCert.conn.end(); // close db connection
在dbContext.query(...)
:
var $Q = require('Q');
function execQuery(connection, query) {
console.log("[backend][context] EXEC QUERY: " + query);
$Q.nfcall(connection.query, query)
.then(function (err, results) {
var ret = {};
if (err) {
// log
var errPkt = getErrPacket(err);
console.log("QUERY ERROR[" + errPkt.errCode + ": " +
errPkt.errConst + "]: " + errPkt.errMessage);
ret = {
hasErr: true,
errPacket: errPkt
};
} else {
ret = {
hasErr: false,
okPacket: {
resType: results.constructor.name,
resLength: results.length,
results: results
}
};
}
// is this correct?
return function () {
return ret;
};
})
.then(function (ret) {
// how do I then return ret to the caller?
})
.done();
}
我只是有点迷失方向(如果可能的话)。在我的应用程序的较低级别回调是可以的,但我不想最终得到一个充满回调意大利面的菜。
答案 0 :(得分:2)
通过承诺,您只需将承诺退还给来电者:
function execQuery(connection, query) {
console.log("[backend][context] EXEC QUERY: " + query);
return $Q.nfcall(connection.query, query)
.then(function(results) {
return {
hasErr: false,
okPacket: {
resType: results.constructor.name,
resLength: results.length,
results: results
}
};
})
.catch(function(err) {
// This doesn't necessarily mean a database error because
// all errors are caught here
if (false /*
TODO logic that checks if the err is not a database error
in which case you should just rethrow
*/) {
throw err;
}
var errPkt = getErrPacket(err);
console.log("QUERY ERROR[" + errPkt.errCode + ": " +
errPkt.errConst + "]: " + errPkt.errMessage);
return {
hasErr: true,
errPacket: errPkt
};
});
}
然后调用者可以使用返回的promise:
dbContext.query(userCert.conn, dbQuery.BuildQuery(query))
.then(function(results) {
// It is really weird to have to check for error in the success
// case but whatever floats your boat
if (!results.hasErr) {
var models = results.okPacket.results.map(function(result) {
return new model(result);
});
}
})
.finally(function() {
userCert.conn.end();
})
.done();
答案 1 :(得分:0)
承诺仍然是回调。它们不会改变代码的实际机制。唯一的区别是promises允许你取消嵌套回调。但你还在使用回调:
// regular callbacks:
do_something(function(x){
do_something_else(function(y){
do_last_thing();
});
});
// with promises:
do_something()
.then(function(x){
do_something_else();
})
.then(function(y){
do_last_thing();
});
您无法将值返回给调用者,因为代码是异步运行的。与promises的唯一区别是,不是传递IN回调,而是返回一个对象(promise),它有一个名为then
的方法,你传递回调。