QnA

await

Q&A 정리: await

await 연산자란 무엇인가?

await는 비동기 작업(Promise)이 완료될 때까지 기다린 뒤 그 결과 값을 꺼내오는 연산자다. 택배를 주문하고 도착할 때까지 기다렸다가 상자를 여는 것과 같다. 작업이 실패하면 에러를 던진다.

The await operator is used to wait for a Promise and get its fulfillment value.

The fulfillment value of the promise or thenable object, or, if the expression is not thenable, the expression's own value.

If the promise is rejected, the await expression throws the rejected value. The function containing the await expression will appear in the stack trace of the error. Otherwise, if the rejected promise is not awaited or is immediately returned, the caller function will not appear in the stack trace.


await는 실행 순서에 어떤 영향을 미치는가?

await를 만나면 해당 함수의 실행이 일시 중단되고, 다른 코드가 먼저 실행될 기회를 얻는다. 이미 결과가 준비되어 있어도 마찬가지로 다른 대기 중인 작업이 먼저 처리된 뒤에 재개된다.

When the awaited expression's value is resolved, another microtask that continues the paused code gets scheduled. This happens even if the awaited value is an already-resolved promise or not a promise: execution doesn't return to the current function until all other already-scheduled microtasks are processed.

async function foo(name) {
  console.log(name, "start");
  await console.log(name, "middle");
  console.log(name, "end");
}
 
foo("First");
foo("Second");
 
// First start
// First middle
// Second start
// Second middle
// First end
// Second end

return await를 사용해야 하는가?

return await은 불필요하다고 알려져 있지만, 실제로는 return promise보다 같거나 더 빠르다. 엔진 최적화 덕분에 성능 차이가 없으므로, 스타일 외의 이유가 없다면 return await를 쓰는 것이 거의 항상 낫다.

Contrary to some popular belief, return await promise is at least as fast as return promise, due to how the spec and engines optimize the resolution of native promises. There's a proposal to make return promise faster and you can also read about V8's optimization on async functions. Therefore, except for stylistic reasons, return await is almost always preferable.


.catch()는 프로미스 함수의 동기 에러를 처리하는가?

프로미스를 반환하는 함수가 동기적으로(즉시) 에러를 던지면 .catch()로는 잡을 수 없다. 이런 경우에는 try...catch를 써야 안전하게 에러를 처리할 수 있다.

If promisedFunction() throws an error synchronously, the error won't be caught by the catch() handler. In this case, the try...catch statement is necessary.