繁体   English   中英

NodeJS-控制器-来自集合+ forEach的多个查询

[英]NodeJS - controller - multiple queries from collections + forEach

混乱诺言和异步等待。 想获得您的建议,在控制器以下情况下的最佳实践是什么? 现在,在将数据传递给客户端之前,它不会获取用户详细信息。

我正在使用NodeJS在服务器端做一个简单的API端点。 控制器正在进行两个查询,以仅将结果作为json对象完成给客户端。 是的,有这个无用的run []数组,但是在构建整个事件结果时使用它:)

 exports.runresults3 = function(req, res) { // Route is passing ID console.log('id', req.params.id); // Test results object to fill const resultsParams = { run: [{ runid: {}, endtimeid: [], userid: [], endtime: [], username: [], }] } // Run objectid resultsParams.run[0].runid = req.params.id; // Get the endtimes by location/stage Endtime.find({stage: req.params.id}) .then(data => { // First loop data.forEach(value => { resultsParams.run[0].endtimeid.push(value._id); resultsParams.run[0].userid.push(value.user); resultsParams.run[0].endtime.push(value.endtime); }) }) .then(() => { // Second loop to get user details for results object resultsParams.run[0].userid.forEach((userId, i) => { TempUser.findById(userId) .then(userdetails => { console.log('userdetails.name', userdetails.name); resultsParams.run[0].username.push(userdetails.name); }); }) }) .then(() => { res.json(resultsParams); }); } 

/////////////客户端将获取json如下

{
"run": [
    {
        "runid": "5ae850d51717862590dc30d4",
        "endtimeid": [
            "5aec482d98555332145eccd3",
            "5aec48c098555332145eccd6",
            "5aec4a2c98555332145eccda",
            "5aec4ab398555332145eccdd",
            "5aec4bb998555332145ecce1",
            "5aec4e42c3bcbb196c8474fc",
            "5aec4e44c3bcbb196c8474fe",
            "5aec4e45c3bcbb196c847500"
        ],
        "userid": [
            "5aec13b098555332145eccbe",
            "5ae869c797e54a37f498c98f",
            "5aec4a1298555332145eccd7",
            "5aec4a1298555332145eccd7",
            "5aec4ba698555332145eccde",
            "5aec13a598555332145eccbc",
            "5ae869c797e54a37f498c98f",
            "5aec13b098555332145eccbe"
        ],
        "endtime": [
            24424,
            3280,
            11858,
            38874,
            5738,
            40384,
            50906,
            36717
        ],
        "username": []
    }
]

}

 exports.runresults3 = function(req, res) { // Route is passing ID console.log('id', req.params.id); // Test results object to fill const resultsParams = { run: [{ runid: {}, endtimeid: [], userid: [], endtime: [], username: [], }] } // Run objectid resultsParams.run[0].runid = req.params.id; Endtime.find({stage: req.params.id}) .then(data => { return Promise.all(data.map(record => { TempUser.findById(record.user) .then(userdetails => { return { endtimeid: record._id, userid: record.user, endtime: record.endtime, username: userdetails.name }; }) })) .then(detailRecords => { return detailRecords.reduce((acc, curr) => { acc.endtimeid.push(curr.endtimeid); acc.userid.push(curr.userid); acc.endtime.push(curr.endtime); acc.username.push(curr.username); return acc; },resultsParams.run[0]); }) .then(() => { res.json(resultsParams); }); }); } 

如果您需要将结果累积到此结果对象中的“关联数组”样式中,则可能是我这样做的方式。

话虽如此,我很可能会尝试将结果作为一系列运行结果返回-类似于以下内容...

{
  "run": [
    {
      "runid": "5ae850d51717862590dc30d4",
      "results": [
        {
          "endtimeid": "5aec482d98555332145eccd3",
          "userid": "5aec13b098555332145eccbe",
          "endtime": 24424,
          "username": "User123"
        },
        {
          "endtimeid": "5aec48c098555332145eccd6",
          "userid": "5ae869c797e54a37f498c98f",
          "endtime": 3280,
          "username": "User234"
        }
      ]
    }
  ]
}

我相信下面的代码应该做到这一点。

 exports.runresults3 = function(req, res) { // Route is passing ID console.log('id', req.params.id); // Test results object to fill const resultsParams = { run: [{ runid: {}, results: [] }] } // Run objectid resultsParams.run[0].runid = req.params.id; Endtime.find({stage: req.params.id}) .then(data => { return Promise.all(data.map(record => { TempUser.findById(record.user) .then(userdetails => { return { endtimeid: record._id, userid: record.user, endtime: record.endtime, username: userdetails.name }; }) })) }) .then(results => resultsParams.run[0].results = reuslts) .then(() => res.json(resultsParams)); } 

当然,可能还需要进行更多的可读性重构,而填充结果的最后一步没有使用先前流程的结果这一事实让我有些困扰-但我会尽量避免出现副作用,因此可能就是我

这是建议的编辑版本:)但仍然缺少用户详细信息,看起来像promise.all没有等待“ TempUser.findById(record.user)”查询。

1我创建了一个新事件,运行,3个用户和3个结果。

2然后我在数据库调用中设置了一些日志

3然后我向邮递员提出了要求

Postman GET请求后,从本地主机登录的日志如下所示:

$节点应用程序服务器在5000个Mongodb上启动,已连接ID 5aeebd8a1b5ddf1424c25194

  1. 从数据库获取结束时间

[{创建:2018-05-06T08:32:46.359Z,_id:5aeebdae1b5ddf1424c25199,结束时间:23204,用户:5aeebd751b5ddf1424c25191,阶段:5aeebd8a1b5ddf1424c25194,__v:0},{创建:2018-05-06TZ.32。 _id:5aeebdb11b5ddf1424c2519b,结束时间:17149,用户:5aeebd7b1b5ddf1424c25192,阶段:5aeebd8a1b5ddf1424c25194,__v:0},{创建:2018-05-06T08:32:51.769Z,_id:5aeebdb31b5ddf1424c2519d,结束时间:10840,用户:5aeebd7f1b5ddf1424c25193,阶段:5aeebd8a1b5ddf1424c25194 ,__v:0}]

  1. 将结果设置为对象

[undefined,undefined,undefined]这应该是链上的最后一个吗?

  1. 从数据库获取用户详细信息

{date:2018-05-06T08:31:49.673Z,_id:5aeebd751b5ddf1424c25191,name:'Firstame Lastname1',__v:0} 2.从数据库中获取用户详细信息{date:2018-05-06T08:31:55.562Z, _id:5aeebd7b1b5ddf1424c25192,名称:'Firstame Lastname2',__v:0} 2.从数据库中获取用户详细信息{日期:2018-05-06T08:31:59.906Z,_id:5aeebd7f1b5ddf1424c25193,名称:'Firstame Lastname3',__v:0 }

这是通过以下代码实现的:

 exports.runresults3 = function(req, res) { // Route is passing ID console.log('id', req.params.id); // Test results object to fill const resultsParams = { run: [{ runid: {}, results: [] }] } // Each run objectid resultsParams.run[0].runid = req.params.id; Endtime.find({stage: req.params.id}) .then(data => { console.log('1. Get endtimes from database', data); return Promise.all(data.map(record => { TempUser.findById(record.user) .then(userdetails => { console.log('2. Get user details from database', userdetails); return { endtimeid: record._id, userid: record.user, endtime: record.endtime, username: userdetails.name }; }) })) }) .then(results => { console.log('3. Set results to object', results); console.log('This should be the last one at chain?'); resultsParams.run[0].results = results; }) .then(() => res.json(resultsParams)); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM