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



