![](/img/trans.png)
[英]stop multiple service controller queries inside NodeJs promise while loop
[英]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
[{創建: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}]
[undefined,undefined,undefined]這應該是鏈上的最后一個嗎?
{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.