简体   繁体   English

如何在1个get调用nodejs中运行多个查询

[英]How to run more than one query in 1 get call nodejs

app.get('/projects/:company_id', function(req, res){
    var company_id = req.params.company_id;

    //query1
    db.projects.count({"company_id": company_id },function(err, doc){   
        res.json(doc);
    });
    //query2
    db.projects.find({"company_id": company_id },function(err, doc){    
        res.json(return_data);
    });
});

Basically I want these two queries to run in parallel and then send the output to front end. 基本上,我希望这两个查询并行运行,然后将输出发送到前端。 I am not sure how to achieve that, guys help!. 我不确定如何实现这一目标,伙计们! Also is there an easy way to separate these two results in front end. 还有一种简便的方法可以在前端将这两个结果分开。 I am using angular js. 我正在使用角度js。

You could run them side by side and send the data after both run. 您可以并排运行它们,并在两次运行后发送数据。 Check async library which is one of many libraries to do such operations easily. 检查异步库(是众多库之一)可轻松进行此类操作。

var async = require("async");
async.parallel({
    one: function(callback) {
        db.projects.count({"company_id": company_id },function(err, doc){   
            callback(null, doc)
        });
    },
    two: function(callback) {
        db.projects.find({"company_id": company_id },function(err, doc){    
            callback(null, doc);
        });
    }
}, function(err, results) {
    var payload = {
        count : results.one,
        data: results.two
    }
    res.json(payload);
});

If you want to do it without any additional library, you could do something similar to this: 如果要在没有任何其他库的情况下执行此操作,则可以执行以下操作:

app.get('/projects/:company_id', function(req, res) {
  // Create an object resembling your final response,
  // but replace the values with a promise.
  var futureData = {
    count: new Promise(function(resolve, reject) {
      db.projects.count({'company_id': company_id}, function(err, doc) {
        if (err) {
          return reject(err);
        }
        return resolve(doc);
      });
    }),
    results: new Promise(function(resolve, reject) {
      db.projects.find({'company_id': company_id}, function(err, doc) {
        if (err) {
          return reject(err);
        }
        return resolve(doc);
      });
    }),
  };

  var keys = Object.keys(futureData);

  // Wait until all promises are resolved.
  Promise.all(
    keys.map(key => futureData[key])
  )
    // Get the response object.
    .then(function(values) {
      // Build an object from the results of the promises,
      // using the same key as in `futureData`.
      return values.reduce(function(data, value, i) {
        var key = keys[i];
        data[key] = value;
        return data;
      }, {});
    })
    .then(function(data) {
      // Send final data.
      res.json(data);
    })
    .catch(function(err) {
      // TODO: Handle error.
    });
});

You want to use Promise.all() to wait both queries are finished. 您想使用Promise.all()等待两个查询都完成。

Of course you need promises inside it, so we wrap each of the two function of yours in a promise , which is fulfilled when the callback is called. 当然,您需要在其中包含Promise,因此我们将您两个函数的每一个都包装在一个Promise中 ,该函数在调用回调时实现。

If one of the two queries fail, then also Promise.all() fails and we send back to the client the error. 如果两个查询之一失败,则Promise.all()失败,我们将错误发送回客户端。

To separate data in the reply I split the data in two fields, count and find . 为了分隔回复中的数据,我将数据分为两个字段, countfind In this way you can read them easily from angularjs and use them as you wish 这样,您可以轻松地从angularjs读取它们,并根据需要使用它们

app.get('/projects/:company_id', function(req, res){
    var company_id = req.params.company_id;

    Promise.all(
      new Promise(resolve, reject) {
        db.projects.count({"company_id": company_id },function(err, doc){   
          if (err) return reject(err);
          resolve(doc);
        });
      },
      new Promise(resolve, reject) {
        db.projects.find({"company_id": company_id },function(err, doc){   
          if (err) return reject(err);
          resolve(doc);
        });
      }
    )
    .then(data) {
      res.json({
        "count": data[0],
        "find": data[1]
      });
    }
    .catch(error) {
      res.json({
        "error": error
      });
    }
});

If you can't use Promises 'cause you're using node.js 0.10.x, you can do something like this: 如果您无法使用Promises,因为您使用的是node.js 0.10.x,则可以执行以下操作:

app.get('/projects/:company_id', function(req, res){
    var company_id = req.params.company_id;
    var reply = {
      find: -1,
      count: -1
    }
    var errorSent = false;

    function sendErr(e) {
      if (errorSent) return; // Do not send twice a reply
      res.json({"error": e});
      errorSent = 1;
    }

    function sendWhenReady() {
      if (reply.count !== -1 && reply.find !== -1) res.send(reply);
    }


    //query1
    db.projects.count({"company_id": company_id },function(err, doc){
        if (err) return sendError(err);
        reply.count = doc;   
        sendWhenReady();
    });
    //query2
    db.projects.find({"company_id": company_id },function(err, doc){ 
        if (err) return sendError(err);   
        reply.find = doc;   
        sendWhenReady();
    });
});

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

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