【问题标题】:Getting empty array in nodejs在nodejs中获取空数组
【发布时间】:2018-07-06 17:20:53
【问题描述】:

我正在发布价值,但我得到的是空数组。我知道它的节点异步问题。但我不知道我该如何解决这个问题。我参考了以下链接:

How do I return the response from an asynchronous call?

但我无法理解。请帮助我理解 Promise 以及如何在我的代码中使用它。

router.post('/inspection_list', function (req, res) {
    var id = req.body.project_id;
    console.log(id)
// res.send("ok")
    db.inspection.findOne({'_id':id},(err,response)=>{
        if(err){
            console.log("error");
        }
        else{
            console.log("Data")
            var inspection = [];
            var data = response.inspection_data;
      var f =  data.map(function (item) { 
                var fielduser = item.fielduser_id
                db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)},(err,user)=>{
                    console.log(user.owner_name);
                    console.log(item.inspection_name)
                    inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})


                })
                });
console.log(inspection) // Here am getting empty value
           // setTimeout(function(){ console.log(inspection) }, 5000); my timeout code


        }
    })
});

【问题讨论】:

  • 你在var data中得到值吗?
  • console.log(user.owner_name);console.log(item.inspection_name) 的输出是什么?
  • 你正在获取用户名和检查名称。如果我为 console.log 设置超时功能,我会得到值
  • 不设置timeout怎么样?你能把超时代码sn-p也贴出来吗?
  • 是的,这就是为什么我说这是异步问题

标签: node.js mongodb asynchronous


【解决方案1】:
router.post('/inspection_list', async function (req, res) {
    var id = req.body.project_id;
    try{
        var response = await db.inspection.findOne({'_id':id})
        var inspection = [];
        var data = response.inspection_data;
        for ( var i = 0; i<data.length; i++){
            var item = data[i]
            var fielduser = item.fielduser_id
            var user = await db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)})
            inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})
       }
    }
    catch(err){
        throw err
    }
})

这里使用async和await,如果你使用node版本>=7.6就可以使用

还要注意以下几点:

router.post('/inspection_list', async 函数(req, res)


分别处理每个错误

router.post('/inspection_list', async function (req, res) {
    var id = req.body.project_id;
    try{
        var response = await db.inspection.findOne({'_id':id})
    }
    catch(err){
        // handle error here
        throw err
    }
    var inspection = [];
    var data = response.inspection_data;
    for ( var i = 0; i<data.length; var item = data[i]
        var fielduser = item.fielduser_id
        try{
            var user = await db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)})
        }
        catch(err){
             // handle error
        }            
        inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})
   }

})

【讨论】:

  • 查看查询“router.post('/inspection_list', async function (req, res)”
  • 在那里添加异步
  • 我会阻止异步文本,也许你会得到它
  • 只是空了
【解决方案2】:

使用 mongoose 是一种简单的方法,它会为所有查询和保存函数返回 Promises,因此您只需执行以下操作: YourModel.findOne({params}).then(() =&gt; {...})

如果您无法做到这一点,就您而言,一个“承诺”的例子是:

var findAndFillArray = (project_id) => new Promise((resolve) => {
    .... your previous code here .... 
    inspection.push({inspection_name:item.inspection_name,field_user_name : 
      user.owner_name})
    if (data.length === inspection.length){  // Or some other preferred condition
       resolve(inspection);
    }
})

然后你会在得到 id 后调用这个函数,就像任何其他函数一样:

var id = req.body.project_id;
findAndFillArray(id).then((inspection_array) => {
    res.send(inspection_array) // Or whatever
})

现在,在 JS 中,map 和所有 list 函数是同步的,你确定错误是因为这个吗?

【讨论】:

  • 不能有data.length === inspection.length不成立的情况吗?届时将如何解决?我认为这是一个有效的场景。
  • @eduPeeth 我只是放置了一个占位符,他可以选择任何他想要的条件,我将使用注释编辑代码
  • @eduPeeth 甚至可能传递 reject 参数并添加拒绝条件以防某些值丢失,现在我不知道代码应该是什么样子,所以我会留下来给作者:)
猜你喜欢
  • 2019-11-08
  • 2019-06-28
  • 2016-10-18
  • 2019-08-08
  • 2021-08-18
  • 2018-06-14
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多