You Don't Know AbortController
James Reed
Infrastructure Engineer · Leapcell

많은 개발자들이 AbortController
를 이해하고 있다고 생각할 수 있지만, 그 기능은 기본적인 것 이상입니다. fetch
요청 취소부터 이벤트 리스너 및 React hook 관리에 이르기까지 다양합니다.
정말로 AbortController
가 얼마나 강력한지 알고 계십니까? 한번 봅시다:
AbortController로 fetch
요청 취소하기
물론 fetch
와 함께 AbortController
를 사용하는 것이 가장 일반적인 사용법입니다.
다음은 AbortController
를 사용하여 취소 가능한 fetch
요청을 만드는 방법을 보여주는 예입니다.
fetchButton.onclick = async () => { const controller = new AbortController(); // 취소 버튼 추가 abortButton.onclick = () => controller.abort(); try { const response = await fetch('/json', { signal: controller.signal }); const data = await response.json(); // 여기에 비즈니스 로직 수행 } catch (error) { const isUserAbort = error.name === 'AbortError'; // AbortController를 사용하여 요청이 취소되면 AbortError가 발생합니다. } };
위의 예는 AbortController
가 도입되기 전에는 불가능했던 것, 즉 프로그래밍 방식으로 네트워크 요청을 취소하는 기능을 보여줍니다. 취소되면 브라우저는 fetch
를 중단하여 네트워크 대역폭을 절약합니다. 중요한 것은 취소가 사용자 시작일 필요가 없다는 것입니다.
controller.signal
은 AbortSignal
객체를 제공하여 fetch
와 같은 비동기 작업과의 통신을 가능하게 하고 취소할 수 있도록 합니다.
여러 신호를 단일 신호로 결합하려면 AbortSignal.any()
를 사용할 수 있습니다. 방법은 다음과 같습니다.
try { const controller = new AbortController(); const timeoutSignal = AbortSignal.timeout(5000); const response = await fetch(url, { // 신호가 트리거되면 fetch 중단 signal: AbortSignal.any([controller.signal, timeoutSignal]), }); const data = await response.json(); } catch (error) { if (error.name === 'AbortError') { // 사용자에게 취소 알림 } else if (error.name === 'TimeoutError') { // 사용자에게 시간 초과 알림 } else { // 네트워크 문제와 같은 다른 오류 처리 console.error(`Type: ${error.name}, Message: ${error.message}`); } }
AbortController
와 AbortSignal
의 차이점
- AbortController:
controller.abort()
를 통해 관련 신호를 명시적으로 취소하는 데 사용됩니다. - AbortSignal: 신호 객체를 나타냅니다. 직접적으로 아무것도 취소할 수 없지만 중단된 상태를 전달합니다.
AbortSignal
의 경우 다음을 수행할 수 있습니다.
signal.aborted
를 사용하여 중단되었는지 확인합니다.abort
이벤트 수신:
if (signal.aborted) { } signal.addEventListener('abort', () => {});
AbortController
를 사용하여 요청이 취소되면 서버는 이를 처리하거나 응답을 보내지 않아 대역폭을 절약하고 동시 연결을 줄여 클라이언트 측 성능을 향상시킵니다.
AbortController의 일반적인 사용 사례
WebSocket 연결 취소
WebSocket과 같은 이전 API는 AbortSignal
을 기본적으로 지원하지 않습니다. 대신 다음과 같이 취소를 구현할 수 있습니다.
function abortableSocket(url, signal) { const socket = new WebSocket(url); if (signal.aborted) { socket.close(); // 이미 취소된 경우 즉시 중단 } signal.addEventListener('abort', () => socket.close()); return socket; }
참고: AbortSignal
이 이미 중단된 경우 abort
이벤트가 트리거되지 않으므로 이 경우를 미리 확인하고 처리해야 합니다.
이벤트 리스너 제거
전통적으로 이벤트 리스너를 제거하려면 정확히 동일한 함수 참조를 전달해야 합니다.
window.addEventListener('resize', () => doSomething()); window.removeEventListener('resize', () => doSomething()); // 작동하지 않습니다.
AbortController
를 사용하면 더 쉬워집니다.
const controller = new AbortController(); const { signal } = controller; window.addEventListener('resize', () => doSomething(), { signal }); // abort()를 호출하여 이벤트 리스너 제거 controller.abort();
이전 브라우저의 경우 AbortController
를 지원하기 위해 폴리필을 추가하는 것을 고려하십시오.
React Hooks에서 비동기 작업 관리
React에서 effect는 이전 비동기 작업이 완료되기 전에 컴포넌트가 업데이트되면 부주의하게 병렬로 실행될 수 있습니다.
function FooComponent({ something }) { useEffect(async () => { const data = await fetch(url + something); // 데이터 처리 }, [something]); return <>...</>; }
이러한 문제를 피하려면 AbortController
를 사용하여 이전 작업을 취소하십시오.
function FooComponent({ something }) { useEffect(() => { const controller = new AbortController(); const { signal } = controller; (async () => { const data = await fetch(url + something, { signal }); // 응답 처리 })(); return () => controller.abort(); }, [something]); return <>...</>; }
Node.js에서 AbortController 사용하기
최신 Node.js에는 AbortController
와 호환되는 setTimeout
구현이 포함되어 있습니다.
const { setTimeout: setTimeoutPromise } = require('node:timers/promises'); const controller = new AbortController(); const { signal } = controller; setTimeoutPromise(1000, 'foobar', { signal }) .then(console.log) .catch((error) => { if (error.name === 'AbortError') console.log('Timeout was aborted'); }); controller.abort();
브라우저 setTimeout
과 달리 이 구현은 콜백을 허용하지 않습니다. 대신 .then()
또는 await
를 사용하십시오.
고급 스케줄링을 위한 TaskController
브라우저는 작업 우선 순위 지정을 위해 scheduler.postTask()
로 이동하고 있으며 TaskController
는 AbortController
를 확장합니다. 이를 사용하여 작업을 취소하고 동적으로 우선 순위를 조정할 수 있습니다.
const taskController = new TaskController(); scheduler .postTask(() => console.log('작업 실행 중'), { signal: taskController.signal }) .then((result) => console.log(result)) .catch((error) => console.error('오류:', error)); taskController.abort();
우선 순위 제어가 필요하지 않으면 AbortController
를 대신 사용할 수 있습니다.
결론
AbortController
는 최신 JavaScript 개발에서 필수적인 도구로, 비동기 작업을 관리하고 취소하는 표준화된 방법을 제공합니다.
브라우저 및 Node.js 환경 모두에 통합되어 다재다능함과 중요성을 강조합니다.
AbortController
를 모르는 경우 이제 모든 기능을 수용하고 비동기 프로그래밍 툴킷의 초석으로 삼을 때입니다.
Leapcell은 Node.js 프로젝트를 클라우드에 배포하기 위한 최고의 선택입니다.
Leapcell은 웹 호스팅, 비동기 작업 및 Redis를 위한 차세대 서버리스 플랫폼입니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발하십시오.
무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하십시오. 요청도 없고 요금도 없습니다.
탁월한 비용 효율성
- 유휴 요금 없이 사용량에 따라 지불합니다.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리할 수 있도록 자동 확장.
- 운영 오버헤드가 전혀 없습니다. 구축에만 집중하십시오.
설명서에서 자세히 알아보십시오!
X에서 팔로우하세요: @LeapcellHQ