簡體   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