본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

map과 reduce에서 async await 사용하기

avatar
yceffort
2020-12-22 · 2분
2min
2020year
KOoriginal
javascriptasync
function sayHello(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(`Hello, ${name}`), 2000)
  })
}

const message1 = await sayHello('yceffort')
console.log(message1)

요런 비동기 함수가 있고, 이를 map으로 처리한다고 가정해보자.

const names = [
  'yceffort1',
  'yceffort2',
  'yceffort3',
  'yceffort4',
  'yceffort5',
  'yceffort6',
]

const messages = names.map(async (name) => await sayHello(name))
console.table(messages)

이렇게 하면 될 것 같지만?

(6) [Promise, Promise, Promise, Promise, Promise, Promise]
0: Promise {<pending>}
1: Promise {<pending>}
2: Promise {<pending>}
3: Promise {<pending>}
4: Promise {<pending>}
5: Promise {<pending>}

아쉽게도 모든 결과가 pending으로 뜬다. await은 Promise 객체만 기다려 주기 때문에 그런 것으로 보인다. 반변에 우리가 넘긴 것은 list다.

따라서 이를 정상적으로 실행하기 위해서는 Promise.all을 사용해야 한다.

const promiseMessages = await Promise.all(
  names.map(async (name) => await sayHello(name)),
)
console.log(promiseMessages)
;[
  'Hello, yceffort1',
  'Hello, yceffort2',
  'Hello, yceffort3',
  'Hello, yceffort4',
  'Hello, yceffort5',
  'Hello, yceffort6',
]

그렇다면 reduce의 경우에는 어떻게 처리하면 좋을까?

const oddMessages = names.reduce(async (prev, current, index) => {
  if (index % 2 > 0) {
    return [...prev, await sayHello(current)]
  } else {
    return prev
  }
}, [])

이렇게 하면 당연히 안될 것이다. 여기에서 prev는 기존의 값이 아닌 Promise일 것이다.

const oddMessages = await names.reduce(async (prev, current, index) => {
  const prevResult = await prev.then()
  if (index % 2 === 0) {
    const result = await sayHello(current)
    return Promise.resolve([...prevResult, result])
  } else {
    return Promise.resolve(prevResult)
  }
}, Promise.resolve([]))

기존에 있던 모든 return을 Promise.resolve로 감싸고, 이전에 넘어온 prev는 then처리를 했다.

;['Hello, yceffort1', 'Hello, yceffort3', 'Hello, yceffort5']

관련 글

  • #javascript#error-handling#async

    uncaught async error를 올바르게 처리하기

    async가 있으면 함수 실행이 뒤로 넘어간다니까요?

    2021-08-23·18분
  • #javascript#async

    no return, await, return, await return 의 차이

    try catch 블록에서는 동작이 다르네

    2021-02-03·3분
  • #turbopack#nextjs#bundler

    Next.js turbopack에서 싱글톤이 두 개가 됐다: scope hoisting 버그와 순환 import

    Next.js 16 turbopack 프로덕션 빌드에서 모듈 스코프 싱글톤이 런타임에 두 개가 됐다. 같은 동기 구간에서 조건 판정이 뒤집히고, 응답이 도착해도 타임아웃이 나는 증상을 번들 산출물로 추적한 기록. scope hoisting의 부분 병합, 순환 import, 이미 고쳐져 있던 upstream 버그, 그리고 뒤늦게 돌린 단일 변수 실험까지.

    2026-08-19·28분
  • #javascript#animation#web-animations-api

    number-flow를 구형 브라우저로 이식하기: 다섯 가지 결정과 두 가지 번복

    number-flow가 애니메이션을 켜는 최소 버전은 Chrome 125, Safari 17.2다. 이 하한을 Chrome 66과 WebKit 16.4까지 내리는 포크를 만들면서 내린 결정들과, 뒤집게 된 판단 두 가지, 그리고 자동 강등을 포기한 Safari 버그 조사의 기록.

    2026-08-11·44분

새 글을 놓치고 싶지 않으시다면 RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다. 발표·기술 자문·기고 문의는 이곳에서 받고 있습니다.

← Back to the blogIssue on GitHub →