상세 컨텐츠

본문 제목

[javascript-issue01] for문과 비동기🥴

본문

🥴직면한 문제 상황

// 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

 

 

 

관련글 더보기

댓글 영역