// A 영역에 코드가 들어감
router.get('/', async (req, res) => { //async
try {
const students = await JoinedUser.find(req.query, ["userId", "alias", "jobId"])
.populate('userId', 'email name alias jobId').populate('jobId').exec()
/* A영역 */
res.json(result)
} catch (err) {
res.status(500).json({ success: false, error: err });
}
})
(1.1)
// map이 비동기 함수 임을 인지하지 못한 잘못된 코드
let result = []
students.map(async(v,i)=>{
const account=await Account.findOne({'studentId':v._id})
await result.push({'name':v.userId.name,'email':v.userId.email,
'alias':v.alias,'job':v.jobId,'balance':account.currentBalance})
//console.log(i,result)
})
(1.2)
// map이 비동기 함수 임을 인지하지 못한 잘못된 코드
let result = await students.map(async(v,i)=>{
const account=await Account.findOne({'studentId':v._id})
return {'name':v.userId.name,'email':v.userId.email,
'alias':v.alias,'job':v.jobId,'balance':account.currentBalance}
})
console.log(result) // pending 반환
1.2) map은 비동기 함수이므로(콜백반환) 내부 함수가 끝나기전에 map이 끝나버린다. 그래서 pending이 리턴된다.
(2)
//재대로 된 코드
let result = await Promise.all(
students.map(async (v, i) => {
const account = await Account.findOne({ 'studentId': v._id })
return {
'name': v.userId.name, 'email': v.userId.email,
'alias': v.alias, 'job': v.jobId, 'balance': account.currentBalance
}
})
)
모든 map 의 비동기 콜백 함수들이 끝날때까지(fulfiled) 기다린 다음에 그 결과를 result에 전달하도록 한다.
•함수 내부의 비동기로 동작하는 코드가 완료되지 않았다 해도 기다리지 않고 즉시 종료한다. 따라서 비동기 함수 내부의 비동기로 동작하는 코드에서 처리 결과를 외부로 반환하거나 상위 스코프의 변수에 할당하면 기대한 대로 동작하지 않는다.
https://eundms.tistory.com/238