【问题标题】:How to send headers after loop循环后如何发送标头
【发布时间】:2019-07-30 23:50:03
【问题描述】:

我想找到一个用户,其模型包含一系列城市(例如:[马德里、伦敦、莫斯科、布宜诺斯艾利斯等])

这是模型:

var UserSchema = Schema({
    name: String,
    surname: String,
    userName: String,
    email: String,
    password: String,
    rol: String,
    suscriptionDate: Date,
    cities:[String],
    citiesPopulate:[]
});

一旦我找到了用户,我想遍历这个数组以使用每个城市作为参数,以便找到我在模型 City 上拥有的信息,只是为了将坐标添加到 user.citiesPopulate

function findUsersCities(req,res){
    let id=req.body._id;

    User.findById(id,function(err,userFound){
        if(err){
            console.log(err)
        }else{

            for(let i=0;i<userFound.cities.length;i++){

                City.findOne({'city':userFound.cities[i]},function(err,citiesFound){
                    if(err){
                        console.log(err)
                    }else{
                        userFound.citiesPopulate.push(citiesFound.coords);
                        console.log(userFound)
                    }
                })
            } 

        }
    })
}

而且,一旦每个城市的所有信息都添加到 userFound.citiesPopulate (现在只是带有一对坐标的数组),我想使用 res.status(200).send({userFound }) 在我的邮递员控制台上查看结果,如下所示(三个城市和三对坐标):

{ cities: [ 'Bilbao', 'Madrid', 'Barcelona' ],
  citiesPopulate: [ [ -3.68, 40.4 ], [ -2.97, 43.25 ], [ 2.18, 41.38 ] ],
  _id: 5c82c2e5cfa8d543d0133dd6,
  name: 'pruebas35',
  surname: 'pruebas35',
  userName: 'pruebas35',
  email: 'pruebas35@prueba.es',
  password: '$2a$10$eSue5gw7r4dFPtwD8qzJhODcvvNFaRkeQYRAOPO9MCBsy3Djhkffq',
  rol: 'user',
  suscriptionDate: 2019-03-08T19:30:45.075Z,
  __v: 0 }

但如果我将 res.status 输入到循环中,它会被发送,但我无法获得全部信息。

我想知道这个问题的解决方案。

【问题讨论】:

  • 如果我在第一个查询之后使用回调函数,即通过 Id 找到用户的回调函数,我会收到一条错误消息:TypeError: Invalid select() argument。必须是字符串或对象。但参数实际上是一个参数

标签: node.js mongoose


【解决方案1】:

正如 Carlos 所指出的,由于数据库请求的异步性质,这将不起作用。我这样做的方法是使用 async/await 使代码同步,如下所示:

function findUsersCities(req,res){
    let id=req.body._id;

    User.findById(id,async function(err,userFound){
        if(err){
            console.log(err)
        }else{
            try {

                for(let i=0;i<userFound.cities.length;i++){

                    let cityFound = await City.findOne({'city':userFound.cities[i]});

                    userFound.citiesPopulate.push(cityFound.coords);
                }

                //complete userFound
                console.log(userFound);

            } catch (e) {
                console.log(e);
            }

        }
    })
}

注意User.findById 的回调函数中关键字async 的使用。如果 await 功能位于标有 async 关键字的函数内,则只能使用它。

另外,当你没有为任何 Mongoose 查询函数指定回调函数时,它会返回一个 Promise,你只能在 Promise 上使用 await 关键字。

如果promise解析,代码会继续运行,解析的值会在变量cityFound中,否则(如果promise拒绝),会抛出一个execption,所以代码会陷入catch语句,被拒绝的值将在变量e中。

【讨论】:

  • 这是我首先做的,但问题是它返回空坐标数组,因为这是异步的,它处理 res.status(200).send({userFound}) 而不是更快我猜是for循环
  • 你说得对,我很抱歉。编辑了答案,现在检查它是否对您有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
相关资源
最近更新 更多