TIL 35 map에서의 비동기 처리

오늘 array.map()을 이용해 비동기 요청을 하면서 기대한 결과값과 달리 promise가 반환되면서 찾아보고 새로 알게 된 내용에 대해 정리해본다.

보통 쓰던 async, await

async function getInfo(userId) {
  const info = await getUserInfo(userId)
}
getInfo(blahblah)

구글링을 해보면 흔히 볼 수 있는 async, await 코드의 예다.

하지만 Array.map()을 사용하면서 비동기 요청을 해야하는 경우 어떻게 코드를 짜야할까?

map에서 사용하는 async, await

// userId의 형태는 array라고 가정
async function getInfo(userId) {
	return await Promise.all(
    	userId.map(async (id) => {
        	return await getUserInfo(id);
        })
    )
}
getInfo() // [userInfo, userInfo, userInfo]

Promise.all() 로 Array.map()을 감싸줘서 코드를 짜면 된다.

만약 Promise.all 을 쓰지 않는다면?
아래와 같이 코드를 짤 수 있다.

async function getInfo(userId) {
    	return userId.map(async (id) => {
        	return await getUserInfo(id);
        }
    )
}

getInfo(); // [promise, promise, promise]

두번째의 경우 왜 원하는 결과값이 나오지 않을까?
알다시피 await은 promise를 기다려주지만 Array.map에서 promise 배열을 리턴하기 때문이다.
Array.map이 promise를 기다려주게 하기 위한 방법으론 Promise.all(iterable) 이 있다.
Promise MDN

위 설명처럼 Promise.all을 사용하면 iterable 내의 모든 프로스미스가 이행한 뒤 이행, 프로미스가 거부하면 즉시 거부하는 프로미스를 반환한다.
이와 같은 설명을 이용해 짠 코드가 첫 번째 코드다.
즉 각 배열마다 비동기 호출을 하는 map 함수를 Promise.all로 감싸줌으로써 map 함수의 모든 프로미스를 기다린 뒤에 결과에 따른 프로미스를 반환하는 것이다.

좋은 웹페이지 즐겨찾기