Language/JS(Node.js)

[자바스크립트] map 함수에서 비동기 콜백 처리하기

Joonfluence 2022. 3. 28.

학습목표


Promise.all을 활용하여, 비동기 콜백함수의 응답을 처리할 수 있다.

본론


흔히 배열을 순회해, 원하는 형태의 값으로 변환할 때 우리는 Array.prototype.map 함수를 사용합니다. 문제는 map 함수를 순회하는 과정에서 네트워크 요청을 거쳐야 한다면 일반 콜백함수가 아니라, 비동기 콜백을 처리해야 할 것입니다. 이 때, 비동기 콜백 함수가 실행된 결괏값을 리턴 받으려면 어떻게 해야 할까요? Promise 대신 말이죠. 정답은 Promise.all을 사용해주면 됩니다.

Promise.all(iterable)

Promise.all 메서드는 파라미터로 순회 가능한 객체를 전달 받을 수 있습니다. 이 경우에는 map 함수의 리턴 값이 되는 객체가 되겠죠. 리턴 값은 요청이 성공적일 때와 요청이 실패했을 때로 나뉩니다. 전자는 파라미터로 등록된 Promise 요청이 모두 resolve된 상태의 값입니다. 후자는 reject된 상태를 반환합니다. 또 리턴 순서는 실행된 순서입니다.

예시

그럼 구체적으로 예를 들어 보겠습니다. 아래와 같이 3개의 원소를 가진 배열이라면 3번의 비동기 함수를 처리해야 할 것입니다. 이 때 Promise.all을 사용해주면, 3번의 비동기 함수의 응답을 모두 기다린 뒤 해당 요청을 처리할 수 있습니다. 예시이므로 네트워크 요청을 직접 보내긴 어려울 것입니다. 따라서 비동기 함수인 setTimeOut를 Promise로 만들어, 1초를 기다린 후 해당 요청을 받아오도록 처리해보겠습니다. 총 3초의 시간이 지나면 배열의 원소와 인덱스가 출력되는 것을 확인할 수 있습니다. 또한 Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 따라서 올바른 응답을 받기 위해선, await를 앞에 꼭 적어주어야 합니다.


const wait = (timeToDelay) => new Promise((resolve) => setTimeout(resolve, timeToDelay));
const arr = [1, 2, 3];
const asyncRes = await Promise.all(
  arr.map(async (item, idx) => {
    await wait(1000)
    return [item, idx];
  });
);

마무리

이상으로 간단하게 Promise.all을 사용하여 map 함수에서 비동기 콜백 요청을 기다렸다 처리하는 방법에 관하여 알아보았습니다.

반응형

댓글