2016-11-16 49 views
0

我是新来的JavaScript和节点,并且无法从猫鼬查询将结果返回给我可以使用的对象。我的应用程序当前正在将发布请求的主体分析到缓存中,使用缓存对象(mlcRecord.existFixture)中的字段查询数据库,并返回一个抓取其他属性的对象。这部分代码工作正常。但是,额外的属性在.then范围之外是未定义的。猫鼬查询的结果在父范围中不可用

我敢肯定我缺少一些基本的东西,所以任何指导人员可以提供赞赏。

router.route('/mlc') 
.post(function (req,res){ 
    var mlcRecord = new mlcInputObj(req.body); 
    async.series([ 
     function (callback) { 
     function setWattages(mlcRecord) { 

     // load the existFixture TechnologyID 
     ltgTechnologies.findOne({TechnologyID: mlcRecord.existFixture}).exec() 

     // capture the technologyID 
      .then(function(ltgTechnology){ 
       mlcRecord.existFixtureWatts = ltgTechnology.SystemWatts; 
       return mlcRecord; 
      }); 
     } 

     setWattages(mlcRecord); 

     console.log('mlcRecord: ', mlcRecord); // existFixtureWatts displays as undefined 
     callback(); 
    } 
    ], function (err) { 
    res.json(mlcRecord); 
    }); 
}); 
+0

可你把整个文件从你的问题? – num8er

回答

1

您的代码过于复杂。

async.series不适合您的目的。

这里是修复:

router 
    .route('/mlc') 
    .post(function (req,res){ 
    var mlcRecord = new mlcInputObj(req.body); 

    // load the existFixture TechnologyID 
    ltgTechnologies 
     .findOne({TechnologyID: mlcRecord.existFixture}) 
     .exec(function(err, result) { 
     mlcRecord.existFixtureWatts = null; 
     if(result) { 
      mlcRecord.existFixtureWatts = result.SystemWatts; 
     } 
     res.send(mlcRecord); 
     }); 
    }); 

,但如果你想mlcRecord保存到数据库:

router 
    .route('/mlc') 
    .post(function (req,res){ 

    var mlcRecord = new mlcInputObj(req.body); // creating mlcRecord instance 

    mlcRecord.save(function(err) { // inserting to database 
     if(err) return res.status(500).send({err}); 

     // adding to mlcRecord existFixtureWatts 
     ltgTechnologies 
     .findOne({TechnologyID: mlcRecord.existFixture}) 
     .exec(function(err, result) { 
      mlcRecord.existFixtureWatts = null; 
      if(result) { 
      mlcRecord.existFixtureWatts = result.SystemWatts; 
      } 
      res.send(mlcRecord); 
     }); 
    }); 

    }); 
+0

谢谢@ num8er。在测试您的解决方案后,我发现它不适用于我的目的。当我构建基于mlcRecord的数据管道时,实际上我需要async.waterfall。事实证明,我遇到的问题与.execution上下文有关。对于任何对此问题感兴趣的人,我已将我的解决方案作为下面的评论。 – tpick

0

我不能确定到底是什么问题是与执行上下文,但似乎在承诺之外,ltgTechnologies.findOne返回的承诺中的mlcRecord无法访问。立即在setWattages函数中返回承诺,然后绑定合成的承诺,解决了我的问题。我也重新命名了几个字段并移动到一个模块中。下面的代码。

app.js

// some code ... 
router 
.route('/mlc') 
.post(function (req,res){ 

var mlcRecord = new mlcInputObj(req.body); 

async.waterfall([ 

    function (callback) { 
     mlcRecord.setOccSensorScenario(); 
     mlcRecord.setltgTechnologyVals().then(function(){ 
      callback(null); 
     }); 
    }, 
    // more functions to execute sequentially 

], function (err, result) { 
    res.json(mlcRecord); 
}); 
}); 
// some other code ... 

mlcInputObj.js(构造函数)

// constructor 
// ... 
// constructor methods 

mlcInputObj.prototype.setltgTechnologyVals = function() { 
//alias for 'this' used in bind 
var mlcObj = this; 

// load the existFixture TechnologyID 
return Promise.all([ 
    // query ltgTechnologies and set existFixtureWatts 
    ltgTechnologies.findOne({TechnologyID: this.existFixture}).exec() 
    .then((function(fixture){ 
     this.existFixtureWatts = fixture.SystemWatts; 
    }).bind(mlcObj)), 
    // another promise, 
    // last promise 
]}; 
}