Promise.then()을 Async/Await 구문과 혼합하면 안 되는 이유
비동기 JavaScript로 작업할 때 엉킨 코드 혼란에 빠진 적이 있습니까? 여기에는 중첩된 콜백이 있고 거기에는 약속이 있으며 이를 마무리하기 위해 반짝거리는 async/await가 있습니다. 😱 🏃🏼♂️💨
나는 당신에 대해 모르지만 콜백, 약속 및 async/await가 동일한 함수에 혼합되어 있는 것을 보면 그 밑에 있을 수 있는 버그에 겁이 납니다. 🐛
순수한 async/await로 작성된 비동기 코드를 사용하여 작업하고 가장 중요하게 읽는 것은 신선한 공기의 숨결입니다!
코드가 무엇을 하는지 즉시 이해하고 필요한 경우 쉽게 변경할 수 있습니다.
아아아아. 인생은 좋다. 😌
약속 거부 !== 비동기 오류
하지만 Node.js 프로젝트에서 작업하고 프로덕션 로그에서 처리되지 않은 Promise 거부를 보기 시작했을 때 삶은 그렇게 좋지 않았습니다.
일부 디버깅 후 결국 다음 코드를 사용하여 Express 미들웨어 기능에 대한 문제를 추적했습니다. 무엇이 잘못되었는지 알 수 있습니까?
try {
const rates = await getCurrencyConversions();
Price.update({ value: rates.EUR }, { where: { description: "dollar" } })
.then((result) => {
return res.status(200).json({ message: "Successfully updated conversion rate.", result });
});
} catch (error) {
const message = "Failed to update conversion rate.";
log.error(message, { error });
return res.status(500).json({ message });
}
이 코드는 본질적으로 잘못된 것이 아닙니다. 모든 것이 오류 없이 작동하면 예상대로 작동합니다.
일이 예상대로 진행되지 않을 때 우리는 이상한 행동을 알아차립니다.
Price.update()
함수에서 오류가 발생하면 어떻게 됩니까?A: catch 블록에서 오류가 포착되어 기록되고 500 상태 코드가 클라이언트로 전송됩니다.
B: Node.js 프로세스에서 전역
unhandledRejection
이벤트가 발생합니다..
.
.
.
.
당신은 아마도 내가 이것으로 어디로 가고 있는지 짐작할 수 있을 것입니다. 정답은 B입니다.
대부분의 사람들은 try-블록에서 오류가 발생하면 catch-블록에서 오류를 잡아서 처리할 것이라고 예상할 것입니다. 그러나 이 경우에는 약속이 async/await와 다른 오류 처리 메커니즘을 가지고 있기 때문에 이는 사실과 거리가 멉니다.
Price.update()
가 거부하면 가장 가까운 .catch()
메서드를 찾습니다. 아무것도 찾지 못하면 Node.js는 전역unhandledRejection
이벤트를 내보냅니다.설상가상으로 Node.js 15 or higher and your application doesn't have an
unhandledRejection
event listener 을 사용하면 서버가 다운됩니다!.catch()
메서드를 Price.update()
에 추가하여 문제를 해결할 수 있었지만 결국 예외 처리를 담당하는 두 곳(.catch() 메서드 및 catch-block)이 생깁니다. 오류를 한 곳에서 처리하면 코드를 유지 관리하기가 더 쉽습니다.나는 일반적으로 async/await 구문을 고수할 것을 권장합니다. 함수가 약속을 반환하는 경우 async/await를 사용할 수도 있으므로 두 구문을 혼합할 필요가 없습니다. Async/await는 결국 Promise 위에 구축됩니다.
Note: An exception to this rule is when you're running multiple complex asynchronous flows using Promise.all, at which point you likely have a solid understanding of how promises work and you're able to work your way around unexpected behaviour that arises from mixing async/await with Promise.then() syntax.
버그의 원인을 파악한 후 코드를 async/await로 리팩터링하고
.then()
메서드를 제거했습니다.try {
const rates = await getCurrencyConversions();
const result = await Price.update(
{ value: rates.EUR },
{ where: { description: "dollar" } }
);
return res.status(200).json({ message: "Successfully updated conversion rate.", result });
} catch (error) {
const message = "Failed to update conversion rate.";
log.error(message, { error });
return res.status(500).json({ message });
}
그 후, 처리되지 않은 약속 거부가 로그에서 사라지고 삶이 다시 좋아졌습니다! 💫
마스터 비동기 자바스크립트 🚀
무료 5일 이메일 과정을 통해 현대적이고 읽기 쉬운 비동기 코드를 작성하는 방법을 배우십시오.
시각적 그래픽을 통해 비동기 코드를 개별 부분으로 분해하고 최신 async/await 접근 방식을 사용하여 다시 결합하는 방법을 배웁니다. 또한 30개 이상의 실제 연습을 통해 지식을 더 나은 개발자가 될 실용적인 기술로 전환할 수 있습니다.
👉 Get Lesson 1 now
Reference
이 문제에 관하여(Promise.then()을 Async/Await 구문과 혼합하면 안 되는 이유), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/maximization/why-you-shouldnt-mix-promisethen-with-asyncawait-syntax-gl1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)