使用嵌套回调服务GET请求

时间:2019-08-07 12:54:35

标签: node.js asynchronous callback async-await

我有一个通用的Node + Express服务器,可以在其中服务GET请求。其中一些GET请求需要多个数据库查询,这些查询是回调。 这是我的代码示例:

获取路由器:

router.get('/getbalance', function(req, res, next) {
    wallet.createNewAddress()
    .then(result => {
        res.send(result);
    })
    .catch(err => {
        console.log(err);
    });

这是带有回调的函数:

   async createNewAddress()
        {
            pool.query(`SELECT ...`)
            .then (dbres1 => {
                pool.query(`SELECT  ...`)
                .then(dbres2 => {
                        (async() => {
                            var pubkeys = await this.getPublicKeysFromIndexes(wallet.id, index_wallet_1, index_wallet_2, index_wallet_3);
                            var script = this.generateScript(pubkey1, pubkey2, pubkey3);
                        })();   
                })
                .catch(e => {
                    console.log(e.stack);
                })
            }

        })
        .catch(e => {
            console.log(e.stack);
        });
    }

为简洁起见,我删除了冗长的声明。 如您所见,我有多个级别的嵌套承诺。 处理这样的请求的正确方法是什么?我应该返还每个诺言还是应该使用async()同步运行所有内容? 我需要做的是在语句的中间返回script。最后一个返回script的调用是常规同步函数。 感谢任何建议。 谢谢。

1 个答案:

答案 0 :(得分:1)

我相信使用async / await将使您的代码更具可读性,同时基本上遵循相同的逻辑。当然,您将必须意识到需要在代码中添加try / catch处理程序。

如果您使用async / await,您将得到如下所示的结果:

async function createNewAddress()
{
    try {
        let dbres1 = await pool.query(`SELECT ...`);
        let dbres2 = await pool.query(`SELECT  ...`);

        var pubkeys = await this.getPublicKeysFromIndexes(wallet.id, index_wallet_1, index_wallet_2, index_wallet_3);    
        return this.generateScript(pubkey1, pubkey2, pubkey3);;
    } catch (err) {
        // ok something bad happened.. we could skip this handler and let the error bubble up to the top level handler if we're happy with that approach.
        console.error(err);
        // Rethrow or create new error here.. we don't want to swallow this.
        throw err;
    }
}

您可以像以前一样致电:

router.get('/getbalance', function(req, res, next) {
    wallet.createNewAddress()
    .then(result => {
        res.send(result);
    })
    .catch(err => {
        console.log(err);
    });

或使用异步处理程序:

router.get('/getbalance', async function(req, res, next) {
    try {
        let result = await wallet.createNewAddress();
        res.send(result);
    } catch (err) {
        // Also consider sending something back to the client, e.g. 500 error
        console.log(err);
    };
})