ํจ์จ์ ์ธ ์์ฒญ ์ทจ์๋ฅผ ์ํ JavaScript์ AbortController ์ข ํฉ ๊ฐ์ด๋. ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค.
JavaScript AbortController ๋ง์คํฐํ๊ธฐ: ์ํํ ์์ฒญ ์ทจ์
ํ๋ ์น ๊ฐ๋ฐ์ ์ญ๋์ ์ธ ์ธ๊ณ์์ ๋น๋๊ธฐ ์์ ์ ๋ฐ์์ฑ ์๊ณ ๋งค๋ ฅ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ค์ถ์ ๋๋ค. API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ถํฐ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ์ฒ๋ฆฌํ๋ ๊ฒ๊น์ง, JavaScript๋ ์๋ฃํ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์๋ ์์ ์ ์์ฃผ ๋ค๋ฃน๋๋ค. ํ์ง๋ง ์ฌ์ฉ์๊ฐ ์์ฒญ์ด ๋๋๊ธฐ ์ ์ ํ์ด์ง๋ฅผ ๋ ๋๊ฑฐ๋, ํ์ ์์ฒญ์ด ์ด์ ์์ฒญ์ ๋์ฒดํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์ ์ ํ ๊ด๋ฆฌ ์์ด๋ ์ด๋ฌํ ์งํ ์ค์ธ ์์ ์ ๋ฆฌ์์ค ๋ญ๋น, ์ค๋๋ ๋ฐ์ดํฐ, ์ฌ์ง์ด ์๊ธฐ์น ์์ ์ค๋ฅ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ JavaScript AbortController API๊ฐ ๋น์ ๋ฐํ๋ฉฐ, ๋น๋๊ธฐ ์์ ์ ์ทจ์ํ๊ธฐ ์ํ ๊ฒฌ๊ณ ํ๊ณ ํ์คํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
์์ฒญ ์ทจ์์ ํ์์ฑ
์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ด ์๋ค: ์ฌ์ฉ์๊ฐ ๊ฒ์์ฐฝ์ ์ ๋ ฅํ๋ฉด, ๊ฐ ํค ์ ๋ ฅ๋ง๋ค ์ ํ๋ฆฌ์ผ์ด์ ์ด API ์์ฒญ์ ๋ณด๋ด ๊ฒ์ ์ ์์ ๊ฐ์ ธ์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋น ๋ฅด๊ฒ ์ ๋ ฅํ๋ฉด ์ฌ๋ฌ ์์ฒญ์ด ๋์์ ์งํ๋ ์ ์์ต๋๋ค. ๋ง์ฝ ์ด๋ฌํ ์์ฒญ์ด ๋๊ธฐ ์ค์ธ ์ํ์์ ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋ํ๋ฉด, ์๋ต์ด ๋์ฐฉํ๋๋ผ๋ ๊ด๋ จ์ด ์์ผ๋ฉฐ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๊ท์คํ ํด๋ผ์ด์ธํธ ์ธก ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๋ ๊ฒ์ ๋๋ค. ๋ ๋์๊ฐ, ์๋ฒ๋ ์ด๋ฏธ ์ด๋ฌํ ์์ฒญ์ ์ฒ๋ฆฌํ์ ์ ์์ด ๋ถํ์ํ ๊ณ์ฐ ๋น์ฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ํํ ์ํฉ์ ์ฌ์ฉ์๊ฐ ํ์ผ ์ ๋ก๋์ ๊ฐ์ ์์ ์ ์์ํ๋ค๊ฐ ์ค๊ฐ์ ์ทจ์ํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ ๊ฒฝ์ฐ์ ๋๋ค. ๋๋ ๋์ฉ๋ ๋ฐ์ดํฐ์ ์ ๊ฐ์ ธ์ค๋ ๊ฒ๊ณผ ๊ฐ์ ์ฅ๊ธฐ ์คํ ์์ ์ด ์๋กญ๊ณ ๋ ๊ด๋ จ์ฑ ๋์ ์์ฒญ์ด ๋ง๋ค์ด์ ธ ๋ ์ด์ ํ์ํ์ง ์๊ฒ ๋ ์๋ ์์ต๋๋ค. ์ด ๋ชจ๋ ๊ฒฝ์ฐ์, ์งํ ์ค์ธ ์์ ์ ์ ์์ ์ผ๋ก ์ข ๋ฃํ๋ ๊ธฐ๋ฅ์ ๋ค์๊ณผ ๊ฐ์ ์ด์ ๋ก ๋งค์ฐ ์ค์ํฉ๋๋ค:
- ์ฌ์ฉ์ ๊ฒฝํ ํฅ์: ์ค๋๋๊ฑฐ๋ ๊ด๋ จ ์๋ ๋ฐ์ดํฐ ํ์๋ฅผ ๋ฐฉ์งํ๊ณ , ๋ถํ์ํ UI ์ ๋ฐ์ดํธ๋ฅผ ํผํ๋ฉฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น ๋ฅธ ๋ฐ์์ฑ์ ์ ์งํฉ๋๋ค.
- ๋ฆฌ์์ค ์ฌ์ฉ ์ต์ ํ: ๋ถํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ค์ด๋ก๋ํ์ง ์์ ๋์ญํญ์ ์ ์ฝํ๊ณ , ์๋ฃ๋์์ง๋ง ํ์ ์๋ ์์ ์ ์ฒ๋ฆฌํ์ง ์์ CPU ์ฌ์ฉ๋์ ์ค์ด๋ฉฐ, ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ๋ณดํฉ๋๋ค.
- ๊ฒฝ์ ์กฐ๊ฑด(Race Conditions) ๋ฐฉ์ง: ๊ฐ์ฅ ์ต์ ์ ๊ด๋ จ ๋ฐ์ดํฐ๋ง ์ฒ๋ฆฌ๋๋๋ก ๋ณด์ฅํ์ฌ, ๋ ์ค๋๋๊ณ ๋์ฒด๋ ์์ฒญ์ ์๋ต์ด ์ต์ ๋ฐ์ดํฐ๋ฅผ ๋ฎ์ด์ฐ๋ ์๋๋ฆฌ์ค๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
AbortController API ์๊ฐ
AbortController
์ธํฐํ์ด์ค๋ ํ๋ ์ด์์ JavaScript ๋น๋๊ธฐ ์์
์ ์ค๋จ ์์ฒญ ์ ํธ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ AbortSignal
์ ์ง์ํ๋ API, ํนํ ์ต์ fetch
API์ ํจ๊ป ์๋ํ๋๋ก ์ค๊ณ๋์์ต๋๋ค.
ํต์ฌ์ ์ผ๋ก AbortController
๋ ๋ ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ์ง๋๋ค:
AbortController
์ธ์คํด์ค: ์๋ก์ด ์ทจ์ ๋ฉ์ปค๋์ฆ์ ์์ฑํ๊ธฐ ์ํด ์ธ์คํด์คํํ๋ ๊ฐ์ฒด์ ๋๋ค.signal
์์ฑ: ๊ฐAbortController
์ธ์คํด์ค์๋signal
์์ฑ์ด ์์ผ๋ฉฐ, ์ด๋AbortSignal
๊ฐ์ฒด์ ๋๋ค. ์ดAbortSignal
๊ฐ์ฒด๋ ์ทจ์ํ๊ณ ์ ํ๋ ๋น๋๊ธฐ ์์ ์ ์ ๋ฌํ๋ ๊ฒ์ ๋๋ค.
AbortController
๋ ๋ํ ๋จ ํ๋์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๋๋ค:
abort()
:AbortController
์ธ์คํด์ค์์ ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ฐ๊ด๋AbortSignal
์ด ์ฆ์ ํธ๋ฆฌ๊ฑฐ๋์ด ์ค๋จ๋จ์ผ๋ก ํ์๋ฉ๋๋ค. ์ด ์ ํธ๋ฅผ ์์ ํ๋ ๋ชจ๋ ์์ ์ ์๋ฆผ์ ๋ฐ๊ณ ๊ทธ์ ๋ฐ๋ผ ์กฐ์นํ ์ ์์ต๋๋ค.
AbortController๊ฐ Fetch์ ํจ๊ป ์๋ํ๋ ๋ฐฉ์
fetch
API๋ AbortController
์ ๊ฐ์ฅ ์ฃผ๋๊ณ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์
๋๋ค. fetch
์์ฒญ์ ํ ๋, options
๊ฐ์ฒด์ AbortSignal
๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ๋ง์ฝ ์ ํธ๊ฐ ์ค๋จ๋๋ฉด, fetch
์์
์ ์กฐ๊ธฐ์ ์ข
๋ฃ๋ฉ๋๋ค.
๊ธฐ๋ณธ ์์ : ๋จ์ผ Fetch ์์ฒญ ์ทจ์ํ๊ธฐ
๊ฐ๋จํ ์์ ๋ก ์ค๋ช ํด ๋ณด๊ฒ ์ต๋๋ค. API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ถ์ง๋ง, ์ฌ์ฉ์๊ฐ ์์ฒญ์ด ์๋ฃ๋๊ธฐ ์ ์ ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ด๋ํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ฉด ์ด ์์ฒญ์ ์ทจ์ํ ์ ์๊ธฐ๋ฅผ ์ํ๋ค๊ณ ์์ํด ๋ณด์ธ์.
```javascript // ์๋ก์ด AbortController ์ธ์คํด์ค ์์ฑ const controller = new AbortController(); const signal = controller.signal; // API ์๋ํฌ์ธํธ์ URL const apiUrl = 'https://api.example.com/data'; console.log('fetch ์์ฒญ ์์ ์ค...'); fetch(apiUrl, { signal: signal // signal์ fetch ์ต์ ์ ์ ๋ฌ }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { console.log('๋ฐ์ดํฐ ์์ :', data); // ์์ ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ }) .catch(error => { if (error.name === 'AbortError') { console.log('Fetch ์์ฒญ์ด ์ค๋จ๋์์ต๋๋ค.'); } else { console.error('Fetch ์ค๋ฅ:', error); } }); // 5์ด ํ์ ์์ฒญ์ ์ทจ์ํ๋ ์๋ฎฌ๋ ์ด์ setTimeout(() => { console.log('fetch ์์ฒญ ์ค๋จ ์ค...'); controller.abort(); // ์ด๊ฒ์ AbortError์ ํจ๊ป .catch ๋ธ๋ก์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค }, 5000); ```์ด ์์ ์์:
AbortController
๋ฅผ ์์ฑํ๊ณ ๊ทธsignal
์ ์ถ์ถํฉ๋๋ค.- ์ด
signal
์fetch
์ต์ ์ ์ ๋ฌํฉ๋๋ค. - ๋ง์ฝ
controller.abort()
๊ฐ fetch๊ฐ ์๋ฃ๋๊ธฐ ์ ์ ํธ์ถ๋๋ฉด,fetch
๊ฐ ๋ฐํํ๋ ํ๋ก๋ฏธ์ค๋AbortError
์ ํจ๊ป ๊ฑฐ๋ถ(reject)๋ฉ๋๋ค. .catch()
๋ธ๋ก์ ์ดAbortError
๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ํ์ธํ์ฌ ์ค์ ๋คํธ์ํฌ ์ค๋ฅ์ ์ทจ์๋ฅผ ๊ตฌ๋ณํฉ๋๋ค.
์ค์ฉ์ ์ธ ์กฐ์ธ: fetch
์ ํจ๊ป AbortController
๋ฅผ ์ฌ์ฉํ ๋๋ ์ทจ์๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ํญ์ catch
๋ธ๋ก์์ error.name === 'AbortError'
๋ฅผ ํ์ธํ์ธ์.
๋จ์ผ ์ปจํธ๋กค๋ฌ๋ก ์ฌ๋ฌ ์์ฒญ ์ฒ๋ฆฌํ๊ธฐ
ํ๋์ AbortController
๋ฅผ ์ฌ์ฉํ์ฌ ๊ทธ signal
์ ์์ ํ๋ ์ฌ๋ฌ ์์
์ ๋ชจ๋ ์ค๋จ์ํฌ ์ ์์ต๋๋ค. ์ด๋ ์ฌ์ฉ์ ํ๋์ด ์ฌ๋ฌ ์งํ ์ค์ธ ์์ฒญ์ ๋ฌดํจํํ ์ ์๋ ์๋๋ฆฌ์ค์์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๋์๋ณด๋ ํ์ด์ง๋ฅผ ๋ ๋๋ฉด ํด๋น ๋์๋ณด๋์ ๊ด๋ จ๋ ๋ชจ๋ ๋ฏธ๊ฒฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์์ฒญ์ ์ค๋จํ๊ณ ์ถ์ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ 'Users'์ 'Products' fetch ์์
๋ชจ๋ ๋์ผํ signal
์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. controller.abort()
๊ฐ ํธ์ถ๋๋ฉด ๋ ์์ฒญ ๋ชจ๋ ์ข
๋ฃ๋ฉ๋๋ค.
๊ธ๋ก๋ฒ ๊ด์ : ์ด ํจํด์ ๋
๋ฆฝ์ ์ผ๋ก API ํธ์ถ์ ์์ํ ์ ์๋ ๋ง์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ง ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์
์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ตญ์ ์ ์ธ ์ ์์๊ฑฐ๋ ํ๋ซํผ์ ์ ํ ๋ชฉ๋ก, ์ฌ์ฉ์ ํ๋กํ, ์ฅ๋ฐ๊ตฌ๋ ์์ฝ ๋ฑ์ ์ํ ์ปดํฌ๋ํธ๊ฐ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ํ ์ ํ ์นดํ
๊ณ ๋ฆฌ์์ ๋ค๋ฅธ ์นดํ
๊ณ ๋ฆฌ๋ก ๋น ๋ฅด๊ฒ ์ด๋ํ๋ฉด, ๋จ์ผ abort()
ํธ์ถ๋ก ์ด์ ๋ทฐ์ ๊ด๋ จ๋ ๋ชจ๋ ๋๊ธฐ ์ค์ธ ์์ฒญ์ ์ ๋ฆฌํ ์ ์์ต๋๋ค.
`AbortSignal` ์ด๋ฒคํธ ๋ฆฌ์ค๋
fetch
๋ ์ค๋จ ์ ํธ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ์ง๋ง, ๋ค๋ฅธ ๋น๋๊ธฐ ์์
์ ์ค๋จ ์ด๋ฒคํธ์ ๋ํ ๋ช
์์ ์ธ ๋ฑ๋ก์ด ํ์ํ ์ ์์ต๋๋ค. AbortSignal
๊ฐ์ฒด๋ 'abort'
์ด๋ฒคํธ๋ฅผ ์์ ํ ์ ์๊ฒ ํด์ฃผ๋ addEventListener
๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ AbortController
๋ฅผ ์ฌ์ฉ์ ์ ์ ๋น๋๊ธฐ ๋ก์ง์ด๋ ์ค์ ์์ signal
์ต์
์ ์ง์ ์ง์ํ์ง ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํตํฉํ ๋ ํนํ ์ ์ฉํฉ๋๋ค.
์ด ์์ ์์:
performLongTask
ํจ์๋AbortSignal
์ ์ธ์๋ก ๋ฐ์ต๋๋ค.- ์งํ ์ํฉ์ ์๋ฎฌ๋ ์ด์ ํ๊ธฐ ์ํด interval์ ์ค์ ํฉ๋๋ค.
- ๊ฒฐ์ ์ ์ผ๋ก,
'abort'
์ด๋ฒคํธ์ ๋ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผsignal
์ ์ถ๊ฐํฉ๋๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด interval์ ์ ๋ฆฌํ๊ณ ํ๋ก๋ฏธ์ค๋ฅผAbortError
๋ก ๊ฑฐ๋ถํฉ๋๋ค.
์ค์ฉ์ ์ธ ์กฐ์ธ: addEventListener('abort', callback)
ํจํด์ ์ฌ์ฉ์ ์ ์ ๋น๋๊ธฐ ๋ก์ง์ ํ์์ ์ด๋ฉฐ, ์ฝ๋๊ฐ ์ธ๋ถ๋ก๋ถํฐ์ ์ทจ์ ์ ํธ์ ๋ฐ์ํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
`signal.aborted` ์์ฑ
AbortSignal
์๋ ๋ํ ๋ถ๋ฆฌ์ธ ์์ฑ์ธ aborted
๊ฐ ์์ต๋๋ค. ์ด๋ ์ ํธ๊ฐ ์ค๋จ๋์์ผ๋ฉด true
๋ฅผ, ๊ทธ๋ ์ง ์์ผ๋ฉด false
๋ฅผ ๋ฐํํฉ๋๋ค. ์ทจ์๋ฅผ ์์ํ๋ ๋ฐ ์ง์ ์ฌ์ฉ๋์ง๋ ์์ง๋ง, ๋น๋๊ธฐ ๋ก์ง ๋ด์์ ์ ํธ์ ํ์ฌ ์ํ๋ฅผ ํ์ธํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
์ด ์ค๋ํซ์์ signal.aborted
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์๋ชจํ ์ ์๋ ์์
์ ์งํํ๊ธฐ ์ ์ ์ํ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. fetch
API๋ ์ด๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ์ง๋ง, ์ฌ์ฉ์ ์ ์ ๋ก์ง์ ์ด๋ฌํ ํ์ธ์ผ๋ก ์ด์ ์ ์ป์ ์ ์์ต๋๋ค.
Fetch๋ฅผ ๋์ด์: ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก
fetch
๊ฐ AbortController
์ ๊ฐ์ฅ ๋๋๋ฌ์ง ์ฌ์ฉ์์ด์ง๋ง, ๊ทธ ์ ์ฌ๋ ฅ์ AbortSignal
์ ์์ ํ๋๋ก ์ค๊ณ๋ ์ ์๋ ๋ชจ๋ ๋น๋๊ธฐ ์์
์ผ๋ก ํ์ฅ๋ฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
- ์ฅ๊ธฐ ์คํ ๊ณ์ฐ: ์น ์์ปค, ๋ณต์กํ DOM ์กฐ์ ๋๋ ์ง์ฝ์ ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ.
- ํ์ด๋จธ:
setTimeout
๊ณผsetInterval
์AbortSignal
์ ์ง์ ๋ฐ์ง ์์ง๋ง,performLongTask
์์ ์์ ๋ณด์ฌ์ค ๊ฒ์ฒ๋ผ ์ด๋ฅผ ์ง์ํ๋ ํ๋ก๋ฏธ์ค๋ก ๊ฐ์ ์ ์์ต๋๋ค. - ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ๋น๋๊ธฐ ์์
์ ๋ค๋ฃจ๋ ๋ง์ ์ต์ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: ์ผ๋ถ ๋ฐ์ดํฐ ํ์นญ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ์ ๋๋ฉ์ด์
๋ผ์ด๋ธ๋ฌ๋ฆฌ)๊ฐ
AbortSignal
์ง์์ ํตํฉํ๊ธฐ ์์ํ์ต๋๋ค.
์์ : ์น ์์ปค์ AbortController ์ฌ์ฉํ๊ธฐ
์น ์์ปค๋ ๋ฌด๊ฑฐ์ด ์์
์ ๋ฉ์ธ ์ค๋ ๋์์ ๋ถ๋ฆฌํ๋ ๋ฐ ํ๋ฅญํฉ๋๋ค. ์น ์์ปค์ ํต์ ํ๊ณ AbortSignal
์ ์ ๊ณตํ์ฌ ์์ปค์์ ์ํ๋๋ ์์
์ ์ทจ์ํ ์ ์์ต๋๋ค.
main.js
```javascript // ์น ์์ปค ์์ฑ const worker = new Worker('worker.js'); // ์์ปค ์์ ์ ์ํ AbortController ์์ฑ const controller = new AbortController(); const signal = controller.signal; console.log('์์ปค์ ์์ ์ ์ก ์ค...'); // ์์ ๋ฐ์ดํฐ์ signal์ ์์ปค์ ์ ์ก worker.postMessage({ task: 'processData', data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], signal: signal // ์ฐธ๊ณ : Signal์ ์ด๋ ๊ฒ ์ง์ ์ ์กํ ์ ์์ต๋๋ค. // ์์ปค๊ฐ ์์ ๋ง์ signal์ ๋ง๋ค๊ฑฐ๋ ๋ฉ์์ง๋ฅผ ์์ ํ ์ ์๋๋ก // ๋ฉ์์ง๋ฅผ ๋ณด๋ด์ผ ํฉ๋๋ค. // ๋ ์ค์ฉ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ค๋จ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ๋๋ค. }); // ์์ปค์ signal์ ์ฒ๋ฆฌํ๋ ๋ ๊ฒฌ๊ณ ํ ๋ฐฉ๋ฒ์ ๋ฉ์์ง ์ ๋ฌ์ ํตํ๋ ๊ฒ์ ๋๋ค: // ์์ : 'start' ๋ฉ์์ง์ 'abort' ๋ฉ์์ง๋ฅผ ๋ณด๋ ๋๋ค. worker.postMessage({ command: 'startProcessing', payload: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }); worker.onmessage = function(event) { console.log('์์ปค๋ก๋ถํฐ์ ๋ฉ์์ง:', event.data); }; // 3์ด ํ์ ์์ปค ์์ ์ ์ค๋จํ๋ ์๋ฎฌ๋ ์ด์ setTimeout(() => { console.log('์์ปค ์์ ์ค๋จ ์ค...'); // ์์ปค์ 'abort' ๋ช ๋ น ์ ์ก worker.postMessage({ command: 'abortProcessing' }); }, 3000); // ์์ ์ด ๋๋๋ฉด ์์ปค๋ฅผ ์ข ๋ฃํ๋ ๊ฒ์ ์์ง ๋ง์ธ์ // worker.terminate(); ```worker.js
```javascript let processingInterval = null; let isAborted = false; self.onmessage = function(event) { const { command, payload } = event.data; if (command === 'startProcessing') { isAborted = false; console.log('์์ปค๊ฐ startProcessing ๋ช ๋ น์ ๋ฐ์์ต๋๋ค. ํ์ด๋ก๋:', payload); let progress = 0; const total = payload.length; processingInterval = setInterval(() => { if (isAborted) { clearInterval(processingInterval); console.log('์์ปค: ์ฒ๋ฆฌ๊ฐ ์ค๋จ๋์์ต๋๋ค.'); self.postMessage({ status: 'aborted' }); return; } progress++; console.log(`์์ปค: ํญ๋ชฉ ์ฒ๋ฆฌ ์ค ${progress}/${total}`); if (progress === total) { clearInterval(processingInterval); console.log('์์ปค: ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์์ต๋๋ค.'); self.postMessage({ status: 'completed', result: '๋ชจ๋ ํญ๋ชฉ ์ฒ๋ฆฌ๋จ' }); } }, 500); } else if (command === 'abortProcessing') { console.log('์์ปค๊ฐ abortProcessing ๋ช ๋ น์ ๋ฐ์์ต๋๋ค.'); isAborted = true; // isAborted ํ์ธ์ผ๋ก ์ธํด ๋ค์ ํฑ์์ interval์ด ์ค์ค๋ก ์ ๋ฆฌ๋ฉ๋๋ค. } }; ```์ค๋ช :
- ๋ฉ์ธ ์ค๋ ๋์์
AbortController
๋ฅผ ์์ฑํฉ๋๋ค. signal
์ ์ง์ ์ ๋ฌํ๋ ๋์ (์ฝ๊ฒ ์ ์กํ ์ ์๋ ๋ณต์กํ ๊ฐ์ฒด์ด๋ฏ๋ก ๋ถ๊ฐ๋ฅํจ), ๋ฉ์์ง ์ ๋ฌ์ ์ฌ์ฉํฉ๋๋ค. ๋ฉ์ธ ์ค๋ ๋๋'startProcessing'
๋ช ๋ น์ ๋ณด๋ด๊ณ ๋์ค์'abortProcessing'
๋ช ๋ น์ ๋ณด๋ ๋๋ค.- ์์ปค๋ ์ด๋ฌํ ๋ช
๋ น์ ์์ ํฉ๋๋ค.
'startProcessing'
์ ๋ฐ์ผ๋ฉด ์์ ์ ์์ํ๊ณ interval์ ์ค์ ํฉ๋๋ค. ๋ํ'abortProcessing'
๋ช ๋ น์ผ๋ก ๊ด๋ฆฌ๋๋isAborted
ํ๋๊ทธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. isAborted
๊ฐ true๊ฐ ๋๋ฉด ์์ปค์ interval์ ์ค์ค๋ก ์ ๋ฆฌ๋๊ณ ์์ ์ด ์ค๋จ๋์์์ ๋ณด๊ณ ํฉ๋๋ค.
์ค์ฉ์ ์ธ ์กฐ์ธ: ์น ์์ปค์ ๊ฒฝ์ฐ, ์ทจ์๋ฅผ ์ ํธํ๊ธฐ ์ํด ๋ฉ์์ง ๊ธฐ๋ฐ ํต์ ํจํด์ ๊ตฌํํ์ฌ AbortSignal
์ ๋์์ ํจ๊ณผ์ ์ผ๋ก ๋ชจ๋ฐฉํ์ธ์.
๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ๊ณ ๋ ค ์ฌํญ
AbortController
๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ช
์ฌํ์ธ์:
- ๋ช
ํํ ์ด๋ฆ ์ง์ : ์ปจํธ๋กค๋ฌ์ ์ค๋ช
์ ์ธ ๋ณ์ ์ด๋ฆ(์:
dashboardFetchController
,userProfileController
)์ ์ฌ์ฉํ์ฌ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ์ธ์. - ์ค์ฝํ ๊ด๋ฆฌ: ์ปจํธ๋กค๋ฌ์ ์ค์ฝํ๊ฐ ์ ์ ํ๊ฒ ์ง์ ๋์๋์ง ํ์ธํ์ธ์. ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ํด์ ๋ ๋, ๊ทธ์ ๊ด๋ จ๋ ๋ชจ๋ ๋๊ธฐ ์ค์ธ ์์ฒญ์ ์ทจ์ํ์ธ์.
- ์ค๋ฅ ์ฒ๋ฆฌ: ํญ์
AbortError
์ ๋ค๋ฅธ ๋คํธ์ํฌ ๋๋ ์ฒ๋ฆฌ ์ค๋ฅ๋ฅผ ๊ตฌ๋ณํ์ธ์. - ์ปจํธ๋กค๋ฌ ์๋ช ์ฃผ๊ธฐ: ์ปจํธ๋กค๋ฌ๋ ํ ๋ฒ๋ง ์ค๋จํ ์ ์์ต๋๋ค. ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ฌ๋ฌ ๋ ๋ฆฝ์ ์ธ ์์ ์ ์ทจ์ํด์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ๋ฌ ์ปจํธ๋กค๋ฌ๊ฐ ํ์ํฉ๋๋ค. ํ์ง๋ง ํ๋์ ์ปจํธ๋กค๋ฌ๋ ์ฌ๋ฌ ์์ ์ด ๋ชจ๋ ๊ทธ ์ ํธ๋ฅผ ๊ณต์ ํ๋ ๊ฒฝ์ฐ ๋์์ ์ค๋จ์ํฌ ์ ์์ต๋๋ค.
- DOM AbortSignal:
AbortSignal
์ธํฐํ์ด์ค๋ DOM ํ์ค์ด๋ผ๋ ์ ์ ์ธ์งํ์ธ์. ๋๋ฆฌ ์ง์๋์ง๋ง, ํ์ํ ๊ฒฝ์ฐ ์ค๋๋ ํ๊ฒฝ๊ณผ์ ํธํ์ฑ์ ํ์ธํ์ธ์(๋จ, ์ต์ ๋ธ๋ผ์ฐ์ ์ Node.js์์๋ ์ง์์ด ์ผ๋ฐ์ ์ผ๋ก ํ๋ฅญํฉ๋๋ค). - ์ ๋ฆฌ(Cleanup): ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ
์ฒ(React, Vue, Angular ๋ฑ)์์
AbortController
๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ์ปดํฌ๋ํธ๊ฐ DOM์์ ์ ๊ฑฐ๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์๊ธฐ์น ์์ ๋์์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ๋ฆฌ ๋จ๊ณ(์: `componentWillUnmount`, `useEffect` ๋ฐํ ํจ์, `ngOnDestroy`)์์controller.abort()
๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ๊ด์ : ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ๊ฐ๋ฐํ ๋, ๋คํธ์ํฌ ์๋์ ์ง์ฐ ์๊ฐ์ ๊ฐ๋ณ์ฑ์ ๊ณ ๋ คํ์ธ์. ์ฐ๊ฒฐ ์ํ๊ฐ ์ข์ง ์์ ์ง์ญ์ ์ฌ์ฉ์๋ ์์ฒญ ์๊ฐ์ด ๋ ๊ธธ์ด์ง ์ ์์ผ๋ฉฐ, ์ด๋ก ์ธํด ํจ๊ณผ์ ์ธ ์ทจ์ ๊ธฐ๋ฅ์ด ์ฌ์ฉ์ ๊ฒฝํ์ด ํฌ๊ฒ ์ ํ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ๋์ฑ ์ค์ํด์ง๋๋ค. ์ด๋ฌํ ์ฐจ์ด์ ์ ์ผ๋์ ๋๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค.
๊ฒฐ๋ก
AbortController
์ ๊ทธ์ ์ฐ๊ด๋ AbortSignal
์ JavaScript์์ ๋น๋๊ธฐ ์์
์ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์
๋๋ค. ์ทจ์๋ฅผ ์ ํธํ๋ ํ์คํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํจ์ผ๋ก์จ, ๊ฐ๋ฐ์๋ค์ ๋ ๊ฒฌ๊ณ ํ๊ณ ํจ์จ์ ์ด๋ฉฐ ์ฌ์ฉ์ ์นํ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๊ฐ๋จํ fetch
์์ฒญ์ ๋ค๋ฃจ๋ ๋ณต์กํ ์ํฌํ๋ก์ฐ๋ฅผ ์กฐ์จํ๋ , AbortController
๋ฅผ ์ดํดํ๊ณ ๊ตฌํํ๋ ๊ฒ์ ๋ชจ๋ ํ๋ ์น ๊ฐ๋ฐ์์๊ฒ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ์ ์
๋๋ค.
AbortController
๋ก ์์ฒญ ์ทจ์๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ ์ฑ๋ฅ๊ณผ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ํฅ์์ํฌ ๋ฟ๋ง ์๋๋ผ ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ง์ ์ ์ผ๋ก ๊ธฐ์ฌํฉ๋๋ค. ์ํธ์์ฉ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ๋, ์ด ์ค์ํ API๋ฅผ ํตํฉํ์ฌ ๋๊ธฐ ์ค์ธ ์์
์ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , ์ ์ธ๊ณ ๋ชจ๋ ์ฌ์ฉ์์ ๊ฑธ์ณ ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ฐ์์ฑ๊ณผ ์ ๋ขฐ์ฑ์ ์ ์งํ๋๋ก ํ์ธ์.