【问题标题】:In Express.js how can we make res.send to wait for data to be fetched from database在 Express.js 中,我们如何让 res.send 等待从数据库中获取数据
【发布时间】:2019-10-09 11:05:41
【问题描述】:

方法res.send()在从方法中从数据库(Mongodb)获取数据之前返回(空)

 Skills.find({ skillbranch: branches[i]._id }, function (err, skills) {

我们如何在返回之前添加等待或异步?

我正在学习 node/express,但无法在 stackoverflow 上使用 asyncawaitPromise 的其他帖子上的一些答案/示例中使用语法。

const Skills = require('../models/skills.model.js');
const SkillBranch = require('../models/skillbranch.model.js');

exports.getSkills = function (req, res) {
   let branchSkills = [];       

   SkillBranch.find(function (err, branches) {         
     if (branches) {
        var obj = {
            "status": "200",
            "message": "skills",
            "data": branches
        }

        for (var i = 0; i < branches.length; i++) {                
            Skills.find({ skillbranch: branches[i]._id }, function (err, skills) {
                console.log(JSON.stringify(skills)); //this is returning after res.send()
                branchSkills.push(skills);                                        
            })

            if (i == branches.length - 1) {                    
                var obj = {
                    "status": "200",
                    "message": "skills",
                    "data": branchSkills
                }

                //this is returning before Skills.find() is complete
                res.send(JSON.stringify(obj));
            }
         }
     } else {
        var obj = {
            "status": "500",
            "message": "Getting skills ",
            "data": []
        }
        res.send(JSON.stringify(obj));
     }
  })
};

【问题讨论】:

    标签: node.js express async-await


    【解决方案1】:

    这样的事情应该可以工作。

    在 mongo 调用上创建一个承诺。完成后,只需将其转换为数组,将其推送到您的分支技能,并使用您的新更新版本解决承诺。然后使用新的更新版本发送数据,而不是您一直在使用的全局 branchSkills 对象。

    应该注意,我不确定您使用分支技能的目的是什么,但您可能只需使用 skills 解决而不推送到该全局数组?不过,这应该可以解决您的时间问题。

    new Promise((resolve, reject) => {
      Skills.find({ skillbranch: branches[i]._id }).toArray((err, skills) => {
          if (err) {
            reject(err);
          } else {
            branchSkills.push(skills);
            resolve(branchSkills);
          }          
        });
      });
    }).then(updatedBranchSkills => {
      if (i == branches.length - 1) {                    
        var obj = {
          "status": "200",
          "message": "skills",
          "data": updatedBranchSkills
      }
    
      res.send(JSON.stringify(obj));
    });
    

    【讨论】:

    • 不要使用i 来跟踪已完成的承诺。因为这是异步的,所以第二个 promise 可以最后完成,你最终会提前调用 res.send()。如果您使用的是 Promise,请改用 Promise.all()
    【解决方案2】:

    必须Skills.find() 回调内部而不是外部调用res.send()。但是由于您调用了多个Skills.find(),因此您需要跟踪返回了多少回调。为此,您可以使用变量:

    // Keep track of completed find():
    var completed = 0;
    
    for (var i = 0; i < branches.length; i++) {                
        Skills.find({ skillbranch: branches[i]._id }, function (err, skills) {
            console.log(JSON.stringify(skills));
            completed++;
            branchSkills.push(skills);
    
            if (completed == branches.length) {
                var obj = {
                    "status": "200",
                    "message": "skills",
                    "data": branchSkills
                }
                res.send(JSON.stringify(obj)); // INSIDE callback
            }
        }) // <--- note that callback ends here!
     }
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多