【问题标题】:How to run more than one query in 1 get call nodejs如何在 1 中运行多个查询获取调用 nodejs
【发布时间】:2016-11-12 14:59:48
【问题描述】:
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。

【问题讨论】:

  • 检查响应。
  • 什么是return_data
  • @noisypixy 我认为他的意思是合并数据

标签: angularjs node.js rest


【解决方案1】:

您可以并排运行它们并在运行后发送数据。检查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);
});

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      当然你需要在它里面有promise,所以我们把你的两个函数都包装在一个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
            });
          }
      });
      

      如果由于使用的是 node.js 0.10.x 而无法使用 Promises,则可以执行以下操作:

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

      【讨论】:

      • 感谢您的回复,但是在您使用 promise 提供的第一个解决方案中,抛出错误,第二个解决方案正在运行
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      相关资源
      最近更新 更多