본문으로 건너뛰기
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

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

avatar
yceffort
2021-02-03 · 3분
3min
2021year
KOoriginal
javascriptasync

50% 확률로 reject 되는 아래와 같은 함수가 있다고 가정해보자.

async function resolveOrReject() {
  // 1초를 그냥 기다린다.
  await new Promise((_) => setTimeout(_, 1000))

  // 50% 확률로 true false
  const randomResult = Boolean(Math.round(Math.random()))

  if (randomResult) {
    return 'good'
  } else {
    throw Error('bad')
  }
}

그냥 호출

async function a() {
  try {
    resolveOrReject()
  } catch (e) {
    return 'caught!'
  }
}

이 경우 a()는 1초를 기다리지 않고 언제나 undefined를 fulfilled (이행) 할 것이다. 우리가 여기에서 await 하거나 껼과를 기다리지 않으므로, 실패했을 경우에 대해서 처리를 할 수가 없다. 대부분 이런 코드는 실수일것이다.

await

async function b() {
  try {
    await resolveOrReject()
  } catch (e) {
    return 'caught!'
  }
}

이 함수의 경우에는 항상 1초를 기다리며, undefined가 오거나 caught가 올 것이다. resolveOrReject의 결과를 기다리기 때문에, 실패 했을 경우 catch 블록을 실행할 수 있게 되었다. 그러나 실패하지 않았을 경우에는 이 값을 가지고 아무것도 하지 않는다.

return

async function c() {
  try {
    return resolveOrReject()
  } catch (e) {
    return 'caught'
  }
}

이 경우에도 마찬가지로 1초를 기다리며, 성공할 경우 good 이 오고, 실패할 경우에는 caught가 오는 것이 아니고 그냥 에러가 던져진다. 따라서 실패할 경우엔 catch 블록에 들어가지 않는다는 것을 알 수 있다.

return await

async function d() {
  try {
    return await resolveOrReject()
  } catch (e) {
    return 'caught'
  }
}

1초를 기다리며, good이 오거나 caught가 오게 된다. resolveOrReject의 결과를 기다리므로, 에러가 났을 때는 catch 블록으로 , 이행이 되었을 경우 정상적으로 결과를 리턴한다.

위 함수를 나누면 이렇게 볼 수 있다.

async function d() {
  try {
    // resolveOrReject 의 결과를 기다리며, 결과를 변수에 넣는다.
    const result = await resolveOrReject()
    // 만약 위에서 에러가 던져졌다면, catch 블록으로 넘어간다.
    // 그렇지 않으면, 결과를 리턴한다.
    return result
  } catch (e) {
    return 'caught'
  }
}

이 것은 어디까지나 try ... catch 블록에서만 유효하다. 그 외의 영역에서는 return await은 의미하다. async 함수 내에 있는 return await은 프로미스를 기다렸다가 결과가 나올때까지, 현재의 함수를 콜스택에 넣어두며, 외부 promise가 resolve 되기전에 추가로 마이크로 태스크가 생기게 된다. 따라서 try ... catch 블록이 아니라면 단순히 return something으로 처리하면 된다.

https://github.com/eslint/eslint/blob/master/docs/rules/no-return-await.md

관련 글

  • #javascript#error-handling#async

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

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

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

    map과 reduce에서 async await 사용하기

    당연한거 아님?

    2020-12-22·2분
  • #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 →