繁体   English   中英

正确使用承诺返回结果

[英]Proper use of promises to return results

我正在使用“ Q”库进行承诺。

这是场景:

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();
}

我只是在做这件事的路上迷路了(如果可能的话)。 在我的应用程序的较低层中可以进行回调,但是我不想以充满回调意大利面的菜式结束。

使用promise,您只需将promise返回给调用方:

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();

承诺仍然是回调。 它们不会更改代码的实际机制。 唯一的区别是,promise允许您取消嵌套回调。 但是您仍在使用回调:

// 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的唯一区别是,您返回的对象(承诺)不是传递回调,而是传递一个具有方法的对象, then将回调传递给该对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM