본문으로 건너뛰기
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분
  • #javascript#performance#v8

    실행하지 않는 JavaScript를 10MiB까지 늘려봤다

    호출하지 않는 함수가 10MiB 들어 있으면 얼마나 손해일까. 바이트가 만든 비용과 코드 형태가 만든 비용을 갈라 855회 측정했다. 미호출 선언은 MiB당 약 21ms로 CPU를 4배 늦춰도 늘지 않았고, 파일을 읽자마자 실행되는 초기화 코드는 MiB당 201ms를 메인 스레드에 얹었다. 실제 라이브러리에서는 import만 해도 모듈 평가가 실행됐다.

    2026-09-16·54분
  • #nodejs#javascript

    『npm Deep Dive』가 2026년 세종도서 학술부문에 선정되었습니다

    『npm Deep Dive』가 2026년 세종도서 학술부문에 선정되었습니다. 함께 써주신 분, 만들어주신 분, 읽어주신 분들께 감사드립니다.

    2026-09-11·1분

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

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다.

← Back to the blogIssue on GitHub →