Javascript 无法在地图回调中返回修改过的对象。我做错了什么?

Javascript 无法在地图回调中返回修改过的对象。我做错了什么?,javascript,node.js,mongodb,mongoose,array.prototype.map,Javascript,Node.js,Mongodb,Mongoose,Array.prototype.map,这是一条在node.js/express/mongoose上运行的路由。。。 “Department”是Mongoose.js模型 第一个“Department.find”调用返回一个对象数组,其中每个对象如下所示: { _识别号:58a4b5991a1214ff1f2c5406, 名称:"资讯科技",, 经理:58a60a581a1214ff1f2c5415, 母公司:58a4b23c1a1214ff1f2c5405, primaryLoc:[58a5db4c1a1214ff1f2c5414]

这是一条在node.js/express/mongoose上运行的路由。。。 “Department”是Mongoose.js模型

第一个“Department.find”调用返回一个对象数组,其中每个对象如下所示:

{ _识别号:58a4b5991a1214ff1f2c5406, 名称:"资讯科技",, 经理:58a60a581a1214ff1f2c5415, 母公司:58a4b23c1a1214ff1f2c5405, primaryLoc:[58a5db4c1a1214ff1f2c5414] }

我希望返回的JSON包含父部门的名称,而不仅仅是id

I.映射返回的“departments”数组。对“父项”Id执行Department.FindOne。这将成功查找父项的名称。然后,我尝试将“parentName”键添加到对象中。 这似乎可以在控制台中正常工作。log'ParentName'+thisObj.ParentName 尽管返回对象不包含添加的键,但无论我尝试什么。 这是我的密码:提前谢谢

router.get('/departments', function(req, res) {

  Department.find({}, function(err, departments) {
    if (err) throw err

    //Find the names of the parent departments
    let newDepts = departments.map(function(dept) {

      let thisObj = dept
      Department.findOne({ _id : dept.parent })

      .then(function(foundDept){
          if (foundDept) {
            thisObj['parentName'] = foundDept.name
            console.log(`thisObj has the key now?: parentName = ${thisObj.parentName}`) //This works
            console.log(`thisObj: ${thisObj}` ) //Nope. No parentName key?? 
            return thisObj
          } else {
            thisObj['parentName'] = "TopLevelDeptartment"
            return thisObj
          }

      })

    })

    res.json(newDepts)

  })

})
在你的帮助下,这是我的新代码。。。不幸的是,res.body有11个空条目。目前数据库中只有11个部门。。。如果我在find之后将thisObj记录到控制台,它是一个完全填充的对象,因此我知道find函数正在工作。我还可以将parentName记录到控制台,以便知道findOne正在工作。还缺什么

router.get('/departments', function(req, res) {

  Department.find({}, function(err, departments) {
    if (err) throw err


    //Find the names of the parent departments
    Promise.map(departments, function(dept) {
      let thisObj = dept
      Department.findOne({ _id : dept.parent }, function(foundDept){
          if (foundDept) {
            thisObj['parentName'] = foundDept.name
          } else {
            thisObj['parentName'] = "No Parent"
          }
      })

    }).then(function(depts){
      console.log(`depts.length: ${depts.length}`)
      res.json(depts)
    })


  })

}) 

代码中有异步操作。映射部门,但db调用在对象映射之后运行。所以你们返回你们原来的部门,一段时间后你们的Moongose findOne函数返回结果,你们更新了已经处理过的对象。您可以看到它已更新,但不会更改原始对象

蓝鸟承诺的解决方案示例:

var Promise = require('Bluebird')

Promise.map(departments, function(dept) {
      return Department.findOne({ _id : dept.parent }, function(foundDept){
          if (foundDept) {
            dept['parentName'] = foundDept.name
          } else {
            dept['parentName'] = "No Parent"
          }
          return dept
      })
    }).then(function(depts){
      res.json(depts)
    })

Bluebird将负责等待您的findOne结果,并在最后返回已转换的依赖项。

部门的map方法肯定不会知道承诺,它将返回数组而不是承诺。请删除你的第一个片段,只有第二个有效。我是蓝鸟的新手,所以如果这是一个愚蠢的问题,请原谅我。在上面的示例中,您有res.jsonnewDepts。。。。newDepts在哪里声明?它来自承诺。处理完所有部门后,Bluebird将从执行您的功能。然后。。。以Departments作为参数。感谢您的帮助:.thenfunctiondepts{res.jsonnewDepts}是一个打字错误吗?它应该是:.thenfunctiondepts{res.jsondepts}?是的,它是一个打字错误;您将从then回调返回,而不是从map回调返回。您需要从映射回调返回承诺,并在等待所有结果之前使用promise.all,只有在完成所有操作后才调用res.json