diff --git a/5-network/04-fetch-abort/article.md b/5-network/04-fetch-abort/article.md index 6548f81d27..9218cdbb67 100644 --- a/5-network/04-fetch-abort/article.md +++ b/5-network/04-fetch-abort/article.md @@ -1,81 +1,82 @@ +# Fetch: 중단 -# Fetch: Abort +알다시피 `fetch`는 프라미스를 반환합니다. 그리고 자바스크립트에는 일반적으로 프라미스 "중단"이라는 개념이 없습니다. 그렇다면 사이트에서 `fetch`가 더는 필요하지 않음을 나타내는 사용자 액션이 일어날 경우, 진행 중인 `fetch`를 어떻게 중단할 수 있을까요? -As we know, `fetch` returns a promise. And JavaScript generally has no concept of "aborting" a promise. So how can we cancel an ongoing `fetch`? E.g. if the user actions on our site indicate that the `fetch` isn't needed any more. +이러한 경우를 위한 `AbortContoller`라고 하는 특별한 내장 객체가 있습니다. 이 객체는 `fetch`를 비롯한 다른 비동기 작업을 중단하는 데 사용할 수 있습니다. -There's a special built-in object for such purposes: `AbortController`. It can be used to abort not only `fetch`, but other asynchronous tasks as well. +사용법은 매우 직관적입니다. -The usage is very straightforward: +## AbortController 객체 -## The AbortController object - -Create a controller: +컨트롤러를 생성합니다. ```js let controller = new AbortController(); ``` -A controller is an extremely simple object. +컨트롤러는 매우 단순한 객체입니다. + +- 단일 메서드인 `abort()`를 갖습니다. +- `abort`에 대한 이벤트 리스너를 설정할 수 있는 단일 속성 `signal`을 갖습니다. -- It has a single method `abort()`, -- And a single property `signal` that allows to set event liseners on it. +`abort()`가 호출되면 -When `abort()` is called: -- `controller.signal` emits the `"abort"` event. -- `controller.signal.aborted` property becomes `true`. +- `controller.signal`은 `"abort"` 이벤트를 내보냅니다. +- `controller.signal.aborted` 속성은 `true`가 됩니다. -Generally, we have two parties in the process: -1. The one that performs an cancelable operation, it sets a listener on `controller.signal`. -2. The one one that cancels: it calls `controller.abort()` when needed. +일반적으로 이 프로세스는 두 부분으로 나뉩니다. -Here's the full example (without `fetch` yet): +1. `controller.signal`에 설정한 리스너에서 취소 가능한 연산을 수행하는 부분 +2. 필요할 때 `controller.abort()`를 호출하여 취소하는 부분 + +다음은 전체 예시입니다. (아직 `fetch`는 사용하지 않음) ```js run let controller = new AbortController(); let signal = controller.signal; -// The party that performs a cancelable operation -// gets "signal" object -// and sets the listener to trigger when controller.abort() is called -signal.addEventListener('abort', () => alert("abort!")); +// "signal" 객체를 받아서 +// controller.abort()가 호출되었을 때 실행할 리스너를 설정하는 +// 취소 가능한 연산을 수행하는 부분 +signal.addEventListener("abort", () => alert("abort!")); -// The other party, that cancels (at any point later): +// 취소하는 부분 (나중에 어떤 시점에라도) controller.abort(); // abort! -// The event triggers and signal.aborted becomes true +// 이벤트가 트리거되고 signal.aborted는 true가 됩니다. alert(signal.aborted); // true ``` -As we can see, `AbortController` is just a means to pass `abort` events when `abort()` is called on it. +보다시피 `AbortController`는 `abort()`가 호출될 때 `abort` 이벤트를 전달하는 수단일 뿐입니다. -We could implement same kind of event listening in our code on our own, without `AbortController` object at all. +`AbortController` 객체를 사용하지 않더라도 동일한 형태로 이벤트 수신을 구현할 수 있습니다. -But what's valuable is that `fetch` knows how to work with `AbortController` object, it's integrated with it. +그러나 `AbortController`가 가치있는 이유는 `fetch`가 `AbortController` 객체와 함께 작동하는 방법을 알고 있고, 통합되어 있기 때문입니다. -## Using with fetch +## fetch와 함께 사용하기 -To become able to cancel `fetch`, pass the `signal` property of an `AbortController` as a `fetch` option: +`fetch`를 취소하려면 `AbortController`의 `signal`속성을 `fetch` 옵션으로 전달합니다. ```js let controller = new AbortController(); fetch(url, { - signal: controller.signal + signal: controller.signal, }); ``` -The `fetch` method knows how to work with `AbortController`. It will listen to `abort` events on `signal`. +`fetch` 메서드는 `AbortController`와 함께 작동하는 방법을 알고 있습니다. `fetch`는 `signal`에 대한 `abort` 이벤트를 수신합니다. -Now, to to abort, call `controller.abort()`: +중단하려면 `controller.abort()`를 호출합니다. ```js controller.abort(); ``` -We're done: `fetch` gets the event from `signal` and aborts the request. +끝났습니다. `fetch`는 `signal`로부터 이벤트를 받고 요청을 중단합니다. -When a fetch is aborted, its promise rejects with an error `AbortError`, so we should handle it, e.g. in `try..catch`. +`fetch`가 중단되면 프라미스는 `AbortError`와 함께 reject되므로, `try..catch` 같은 방식으로 에러를 적절히 처리해야합니다. -Here's the full example with `fetch` aborted after 1 second: +다음은 1초 후에 `fetch`를 중단하는 전체 예시입니다. ```js run async // abort in 1 second @@ -83,11 +84,12 @@ let controller = new AbortController(); setTimeout(() => controller.abort(), 1000); try { - let response = await fetch('/article/fetch-abort/demo/hang', { - signal: controller.signal + let response = await fetch("/article/fetch-abort/demo/hang", { + signal: controller.signal, }); -} catch(err) { - if (err.name == 'AbortError') { // handle abort() +} catch (err) { + if (err.name == "AbortError") { + // abort() 처리 alert("Aborted!"); } else { throw err; @@ -95,37 +97,37 @@ try { } ``` -## AbortController is scalable +## AbortController는 확장 가능합니다 -`AbortController` is scalable, it allows to cancel multiple fetches at once. +`AbortController`는 확장 가능하며 한 번에 fetch 여러 개를 동시에 취소할 수 있습니다. -Here's a sketch of code that fetches many `urls` in parallel, and uses a single controller to abort them all: +다음은 많은 `urls`을 병렬로 fetch하고 단일 컨트롤러를 사용하여 모두 중단하는 코드입니다. ```js -let urls = [...]; // a list of urls to fetch in parallel +let urls = [...]; // 병렬로 fetch할 url 목록 let controller = new AbortController(); -// an array of fetch promises +// fetch 프라미스 배열 let fetchJobs = urls.map(url => fetch(url, { signal: controller.signal })); let results = await Promise.all(fetchJobs); -// if controller.abort() is called from elsewhere, -// it aborts all fetches +// 어딘가 다른 곳에서 controller.abort()가 호출되면 +// 모든 fetch를 중단합니다 ``` -If we have our own asynchronous tasks, different from `fetch`, we can use a single `AbortController` to stop those, together with fetches. +만약 `fetch`가 아닌 자체 비동기 태스크가 있을 경우에도 단일 `AbortController`를 사용하여 fetch와 함께 중지할 수 있습니다. -We just need to listen to its `abort` event in our tasks: +그저 작업 내에서 `abort` 이벤트를 수신하도록 하면 됩니다. ```js let urls = [...]; let controller = new AbortController(); -let ourJob = new Promise((resolve, reject) => { // our task +let ourJob = new Promise((resolve, reject) => { // 자체 태스크 ... controller.signal.addEventListener('abort', reject); }); @@ -134,15 +136,15 @@ let fetchJobs = urls.map(url => fetch(url, { // fetches signal: controller.signal })); -// Wait for fetches and our task in parallel +// fetch와 자체 태스크를 병렬로 기다립니다 let results = await Promise.all([...fetchJobs, ourJob]); -// if controller.abort() is called from elsewhere, -// it aborts all fetches and ourJob +// 어딘가 다른 곳에서 controller.abort()가 호출되면 +// 모든 fetch와 자체 태스크를 중단합니다 ``` -## Summary +## 요약 -- `AbortController` is a simple object that generates `abort` event on it's `signal` property when `abort()` method is called (and also sets `signal.aborted` to `true`). -- `fetch` integrates with it: we pass `signal` property as the option, and then `fetch` listens to it, so it becomes possible to abort the `fetch`. -- We can use `AbortController` in our code. The "call `abort()`" -> "listen to `abort` event" interaction is simple and universal. We can use it even without `fetch`. +- `AbortController`는 `abort ()` 메서드가 호출될 때 자신의 `signal` 속성에 `abort` 이벤트를 발생시키는 단순한 객체입니다(또한 `signal.aborted`를 `true`로 설정). +- `fetch`와 통합: `signal` 속성을 옵션으로 전달하면 `fetch`가 `abort` 이벤트를 수신하므로 `fetch`를 중단할 수 있습니다. +- 코드에서 `AbortController`를 사용할 수 있습니다. "`abort()` 호출" -> "`abort` 이벤트 수신" 인터랙션은 단순하고 보편적입니다. 심지어 `fetch` 없이도 사용할 수 있습니다.