如何使用Express从一个端点发送多个查询? [英] How do I send multiple queries from one endpoint with Express?

查看:59
本文介绍了如何使用Express从一个端点发送多个查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图多次查询数据库,并构造一个对象,该对象将数据库中的每个响应存储在一个字段中.这是我的代码:

I am trying to query my database several times and construct an object which stores every response from my database in a field. Here is my code:

router.post('/search', (req, res) => {
    var collection = db.get().collection('styles')
    var data = [];

    collection.distinct('make.name', (err, docs) => {
      data.push({'make': docs });
    });

    collection.distinct('model', (function (err, docs) {
        data.push({'model': docs });
    }))

    res.send(data);
});

由于NodeJS/Express是异步的,因此无法正常运行.如何重建该端点以进行多个数据库调用(来自同一集合)并返回包含该端点的对象?

Since NodeJS/Express is asynchronous, this isn't working as I would like. How can I reconstruct this endpoint to make several database calls (from the same collection) and return an object containing it?

推荐答案

有多种方法可以做到:

没有承诺,您可以嵌套回调:

Without promises you could nest the callbacks:

router.post('/search', (req, res) => {
    var collection = db.get().collection('styles')
    var data = [];

    collection.distinct('make.name', (err, docs) => {
      if (err) {
        // ALWAYS HANDLE ERRORS!
      }
      data.push({'make': docs });
        collection.distinct('model', (function (err, docs) {
          if (err) {
            // ALWAYS HANDLE ERRORS!
          }
          data.push({'model': docs });
          res.send(data);
        }))
    });
});

这是最简单的方法,但是请注意,如果可以并行执行这两个请求,则效率不高.

This would be the easiest way, but note that it is not efficient if those two requests could be done in parallel.

您可以使用 async 模块:

router.post('/search', (req, res) => {
    var collection = db.get().collection('styles')
    var data = [];

    async.parallel({
      make: cb => collection.distinct('make.name', cb),
      model: cb => collection.distinct('model', cb),
    }, (err, responses) => {
      if (err) {
        // ALWAYS HANDLE ERRORS!
      }
      data.push({'make': responses.make });
      data.push({'model': responses.model });
      res.send(data);
    });
});

请参阅: https://caolan.github.io/async/docs.html#parallel

但这可能仍然不是最方便的方法.

But this may still not be the most convenient method.

如果您要打30次电话,最灵活的方法是:

The most flexible way of doing that if you have 30 calls to make would be to:

  1. 使用返回承诺的函数,而不是使用回调的函数
  2. 如果可以,或者至少基于生成器的协程,请使用async/await
  3. 当逻辑需要按顺序运行时,等待诺言(或屈服诺言)
  4. Promise.all()用于可以并行完成的任何事情
  1. Use functions that return promises instead of functions that take callbacks
  2. Use async/await if you can or at least generator based coroutines
  3. Await on promises (or yield promises) when the logic needs to run in sequence
  4. Use Promise.all() for anything that can be done in parallel

使用异步/等待,您的代码可能如下所示:

With async/await your code could look like this:

    // in sequence:    
    var make = await collection.distinct('make.name');
    var model = await collection.distinct('model');
    // use 'make' and 'model'

或者:

    // in parallel:
    var array = await Promise.all([
      collection.distinct('make.name'),
      collection.distinct('model'),
    ]);
    // use array[0] and array[1]

async / await 的一大优势是错误处理:

A big advantage of async/await is the error handling:

try {
  var x = await asyncFunc1();
  var array = await Promise.all([asyncFunc2(x), asyncFunc3(x)]);
  var y = asyncFunc4(array);
  console.log(await asyncFunc5(y));
} catch (err) {
  // handle any error here
}

您只能在使用 async 关键字创建的函数中使用它.有关更多信息,请参见:

You can only use it inside of a function created with the async keyword. For more info, see:

有关浏览器的支持,请参见:

For support in browsers, see:

有关Node的支持,请参见:

For support in Node, see:

在不支持 async await 的本地支持中,可以使用Babel:

In places where you don't have native support for async and await you can use Babel:

或使用稍微不同的语法,使用基于生成器的方法,例如 co <​​/code>或Bluebird协程:

or with a slightly different syntax a generator based approach like in co or Bluebird coroutines:

查看这些答案以获取更多信息:

See those answers for more info:

  • try/catch blocks with async/await
  • node.js ~ constructing chained sequence of Promise resolves
  • How to run Generator Functions in Parallel?
  • node.js ~ constructing chained sequence of Promise resolves
  • Using async/await + Bluebird to promisifyAll
  • jQuery: Return data after ajax call success

这篇关于如何使用Express从一个端点发送多个查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆