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

时间:2016-07-10 16:02:53

标签: angularjs node.js rest

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);
    });
});

基本上我希望这两个查询并行运行,然后将输出发送到前端。我不知道如何实现这一点,伙计们帮忙! 还有一种简单的方法可以在前端分离这两个结果。我正在使用角度js。

3 个答案:

答案 0 :(得分:0)

您可以并排运行它们并在运行后发送数据。检查async library,这是许多库之一,可以轻松完成此类操作。

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);
});

答案 1 :(得分:0)

如果你想在没有任何额外库的情况下这样做,你可以做类似的事情:

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.
    });
});

答案 2 :(得分:0)

您希望使用Promise.all()等待两个查询完成。

当然你需要在其中使用promises,所以我们将你的两个函数中的每一个都包含在promise中,这在调用回调时就会实现。

如果两个查询中的一个失败,那么Promise.all()也会失败,我们会向客户端发送错误。

要在回复中分隔数据,我会将数据拆分为两个字段countfind。通过这种方式,您可以轻松地从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
      });
    }
});

如果你不能使用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();
    });
});