javascript – 如何使用pg-promise一次性从多个查询中获取结果?

目前我有以下代码获取两个查询的结果
dbro.many("SELECT geoname_id,country_name FROM paises WHERE locale_code=$1 LIMIT 10",data.lang)
   .then(function(countriesData){
      data.countries=countriesData;
      dbro.many("SELECT * FROM categorias")
       .then(function(categoriesData){
         data.categories=(categoriesData)
         console.log(data);
         res.render('layout',data);
         res.end();
      })
       .catch(function(err){
        console.log("error while fetching categories data");
      })
    })
    .catch(function(err){
      console.log("error while fetching countries data",err);
    });

不知怎的,我认为这是不对的.如果我需要在返回回调之前获得许多查询的结果,该怎么办?几个then / catch的嵌套变得丑陋.目标是在呈现页面之前准备好所有数据(在Express中)

解决方法

pg-promise文档有 plenty of examples如何执行多个查询.

初始化

const pgp = require('pg-promise')(/* initialization options */);
const db = pgp('postgres://username:password@host:port/database');

查询相互依赖时,我们应该在任务中链接它们:

db.task('get-user-events',t => {
        return t.one('select * from users where id = $1',123)
            .then(user => {
                return t.any('select * from events where login = $1',user.name);
            });
    })
    .then(data => {
        // data = result from the last query;
    })
    .catch(error => {
        // error
    });

查询没有依赖关系时,我们应该在任务中将它们作为batch执行:

db.task('get-everything',t => {
        return t.batch([
            t.any('select * from users'),t.one('select count(*) from events')
        ]);
    })
    .then(data => {
        // data[0] = result from the first query;
        // data[1] = result from the second query;
    })
    .catch(error => {
        // error
    });

查询更改数据时,我们应该将task替换为tx以进行交易.

请注意,我强调每个语句都带有“should”,因为您可以执行任务或事务之外的所有内容,但由于管理数据库连接的方式,因此不建议这样做.

当您需要为每个HTTP请求执行单个查询时,您应该只对根协议(db对象)执行查询.应始终在任务/事务中执行多个查询.

另见Chaining Queries,其主要点位于底部

If you do not follow the advised approach,your application will perform better under a small load,due to more connections allocated in parallel,but under a heavy load it will quickly deplete the connection pool,crippling performance and scalability of your application.

UPDATE

pg-promise v7.0.0开始,我们可以在一个命令中从多个查询提取结果,这比以前的所有解决方案都高效得多:

db.multi('SELECT * FROM users;SELECT count(*) FROM events')
    .then(data => {
        // data[0] = result from the first query;
        // data[1] = result from the second query;
    })
    .catch(error => {
        // error
    });

或者,如果您使用的是Bluebird,那么:

db.multi('SELECT * FROM users;SELECT count(*) FROM events')
    .spread((users,[{count}]) => {
        // users = array of user records;
        // count = string with the count;
    })
    .catch(error => {
        // error
    });

请参阅新方法multimultiResult.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...