anchor.diff:      .file tsconfig.json
       .file typings.json
   :marked
  +  이번 챕터에서 논의한 코드 파일 목록입니다.
  +
     Here are the code files we discussed in this chapter.
   
   +makeTabs(`
  
positive.code:     .file typings.json
  
  :marked
    ### Keep the app transpiling and running
    Open a terminal/console window. 
    Start the TypeScript compiler, watch for changes, and start our server by entering the command:
  
  
negative.code:   npm start
  
  :marked
    이렇게 하면 Tour of Heroes를 계속 빌드하면서 자동으로 애플리케이션을 실행하고 업데이트 할 수 있습니다.
  
    The application runs and updates automatically as we continue to build the Tour of Heroes.
  
    ## 히어로 서비스 만들기
    ## Creating a Hero Service
  
    우리의 이해관계자들이 앱에 대한 큰 비전을 공유했습니다.
    이들은 히어로를 여러 페이지에 다양한 방법으로 보여주고 싶어 합니다.
    목록에서 히어로를 선택하는 것까지는 했습니다.
    이제 곧 최고의 히어로를 보여주는 대시보드를 만들고 히어로 상세 정보를 수정할 수 있는 독립된 뷰를 만들어 보겠습니다.
    3개의 뷰 모두 히어로 데이터가 필요합니다.
  
    Our stakeholders have shared their larger vision for our app. 
    They tell us they want to show the heroes in various ways on different pages. 
    We already can select a hero from a list.
    Soon we'll add a dashboard with the top performing heroes and create a separate view for editing hero details.
    All three views need hero data. 
  
    현재 `AppComponent`는 화면 표시를 위해 샘플 히어로를 정의하고 있습니다.
    여기에 적어도 2개의 문제점이 보입니다.
    첫째, 히어로를 정의하는 것은 컴포넌트의 역할은 아닙니다.
    둘째, 히어로 목록을 다른 컴포넌트나 뷰에 공유하기가 쉽지 않습니다.
  
    At the moment the `AppComponent` defines mock heroes for display.
    We have at least two objections.
    First, defining heroes is not the component's job. 
    Second, we can't easily share that list of heroes with other components and views. 
  
    이러한 히어로 데이터 획득 업무는 히어로를 제공하고 히어로를 필요로 하는 
    모든 컴포넌트에 공유할 수 있도록 한개의 서비스로 리팩토링할 수 있습니다.
  
    We can refactor this hero data acquisition business to a single service that provides heroes, and 
    share that service with all components that need heroes.
  
    ### 히어로 서비스 만들기
    ### Create the HeroService
  
    `app` 폴더에 `hero.service.ts` 파일을 생성합니다.
  
    Create a file in the `app` folder called `hero.service.ts`. 
  .l-sub-section
    :marked
      여기서 서비스는 소문자 `.service`로 끝나는 작명 규칙을 따랐습니다.
      서비스가 여러 단어라면 소문자 [dash-case](../guide/glossary.html#!#dash-case)로 표기하면 됩니다.
      `SpecialSuperHeroService`는 `special-super-hero.service.ts` 파일에 작성하면 됩니다.
  
      We've adopted a convention in which we spell the name of a service in lowercase followed by `.service`.
      If the service name were multi-word, we'd spell the base filename in lower [dash-case](../guide/glossary.html#!#dash-case).
      The `SpecialSuperHeroService` would be defined in the `special-super-hero.service.ts` file.
  :marked
    `HeroService` 클래스로 명명하고 다른 곳에서 임포트 할 수 있게 익스포트하겠습니다.
  
    We name the class `HeroService` and export it for others to import.
  
  +makeExample('toh-4/ts/app/hero.service.1.ts', 'empty-class', 'app/hero.service.ts (starting point)')(format=".")
  
  :marked
    ### 주입 가능한 서비스
    ### Injectable Services
  
    Angular `Injectable` 함수를 임포트하고 `@Injectable()` 데코레이터를 적용한 것에 주의하세요.
  
    Notice that we imported the Angular `Injectable` function and applied that function as an `@Injectable()` decorator.
  .callout.is-helpful
    :marked
      **괄호를 잊지 마세요!** 괄호를 없애면 발견하기 어려운 에러가 발생할 수 있습니다.
  
      **Don't forget the parentheses!** Neglecting them leads to an error that's difficult to diagnose.
  :marked
    TypeScript는 `@Injectable()` 데코레이터를 발견하면 서비스에 대한 메타데이터 또는
    다른 종속성을 서비스에 주입하기 위해 Angular가 필요로 하는 메타데이터를 내보내게 됩니다.
  
    TypeScript sees the `@Injectable()` decorator and emits metadata about our service, 
    metadata that Angular may need to inject other dependencies into this service.
  
    `HeroService`는 *아직은* 다른 종속성이 없지만 데코레이터를 추가하겠습니다.
    *처음부터* `@Injectable()` 데코레이터를 적용하는 것이
    일관성을 위해서나 미래를 위해서나 "모범적인 사례(best practice)" 입니다.
  
    The `HeroService` doesn't have any dependencies *at the moment*. Add the decorator anyway.
    It is a "best practice" to apply the `@Injectable()` decorator ​*from the start*​ 
    both for consistency and for future-proofing.
  
  :marked
    ### 히어로 가져오기
    ### Getting Heroes
  
    `getHeroes` 메소드 코드조각을 추가합니다.
  
    Add a `getHeroes` method stub.
  +makeExample('toh-4/ts/app/hero.service.1.ts', 'getHeroes-stub', 'app/hero.service.ts (getHeroes stub)')(format=".")
  :marked
    잠시 중요한 부분을 짚어보기 위해 구현부를 살펴보겠습니다.
  
    We're holding back on the implementation for a moment to make an important point.
  
    서비스 소비자는 서비스가 어떻게 데이터를 얻게 되는지 알 수 없습니다.
    `HeroService`는 `Hero` 데이터를 어느 곳에서나 가져올 수 있습니다.
    웹 서비스에서 가져올 수도 있고, 로컬 스토리지에서 가져올 수도 있고,
    또는 샘플 데이터 소스에서 가져올 수도 있습니다.
  
    The consumer of our service doesn't know how the service gets the data. 
    Our `HeroService` could get `Hero` data from anywhere. 
    It could get the data from a web service or local storage
    or from a mock data source.
  
    이것이 바로 컴포넌트에서 데이터 접근부를 제거한 장점입니다.
    우리는 히어로를 사용하는 어떤 컴포넌트도 건드리지 않고
    어떤 이유로든 언제든 원하는 만큼 구현부를 변경할 수 있습니다.
  
    That's the beauty of removing data access from the component.
    We can change our minds about the implementation as often as we like,
    for whatever reason, without touching any of the components that need heroes.
  
  
    ### 샘플 히어로
    ### Mock Heroes  
  
    이미 `AppComponent`에 샘플 `Hero` 데이터가 있습니다. 그곳에 위치하기 적절한 데이터는 아닙니다. 역시 *서비스*에 위치하기도 적절하지 않습니다.
    샘플 데이터를 고유의 파일로 이동하도록 하겠습니다.
  
    We already have mock `Hero` data sitting in the `AppComponent`.  It doesn't belong there. It doesn't belong *here* either.
    We'll move the mock data to its own file.
  
    `app.component.ts`에 있는 `HEROES` 배열을 잘라서 `app` 폴더의 `mock-heroes.ts` 파일에 붙어넣기 합니다.
    히어로 배열이 `Hero` 클래스를 사용할 수 있도록 `import {Hero} ...` 구문 또한 복사합니다.
  
    Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.
    We copy the `import {Hero} ...` statement as well because the heroes array uses the `Hero` class.
  
  +makeExample('toh-4/ts/app/mock-heroes.ts', null, 'app/mock-heroes.ts')
  :marked
    `HEROES` 상수를 익스포트했으므로 다른 곳 &mdash; `HeroService` 같은 곳에서도 임포트 할 수 있습니다.
  
    We export the `HEROES` constant so we can import it elsewhere &mdash; such as our `HeroService`.
  
    한편 `HEROES` 배열을 잘라낸 `app.component.ts`로 돌아와서,
    `heroes` 프로퍼티는 초기화하지 않은 채로 둡니다.
  
    Meanwhile, back in `app.component.ts` where we cut away the `HEROES` array, 
    we leave behind an uninitialized `heroes` property:
  +makeExample('toh-4/ts/app/app.component.1.ts', 'heroes-prop', 'app/app.component.ts (heroes property)')(format=".")
  :marked
    ### 샘플 히어로 반환하기
    ### Return Mocked Heroes
  
    `HeroService`로 돌아와 샘플 `HEROES`를 임포트하고 `getHeroes` 메소드에서 그 값을 반환합니다.
    `HeroService`는 아래와 같습니다.
  
    Back in the `HeroService`  we import the mock `HEROES` and return it from the `getHeroes` method.
    Our `HeroService` looks like this:
  +makeExample('toh-4/ts/app/hero.service.1.ts', 'full', 'app/hero.service.ts')(format=".")
  :marked
    ### 히어로 서비스 사용하기
    ### Use the Hero Service
  
    `AppComponent`를 시작으로 다른 컴포넌트에서도 `HeroService`를 사용할 준비가 되었습니다.
  
    We're ready to use the `HeroService` in other components starting with our `AppComponent`.
  
    언제나처럼 사용하고 싶은 `HeroService`를 임포트하며 시작합니다.
  
    We begin, as usual, by importing the thing we want to use, the `HeroService`.
  +makeExcerpt('toh-4/ts/app/app.component.ts', 'hero-service-import')
  :marked
    서비스를 임포트하면 코드에서 *참조*가 가능합니다.
    어떻게 `AppComponent`는 `HeroService`의 구체화된 런타임 인스턴스를 얻을 수 있을까요?
  
    Importing the service allows us to *reference* it in our code. 
    How should the `AppComponent` acquire a runtime concrete `HeroService` instance?
  
    ### *히어로 서비스*를 *새로* 만드는 것일까요? 그럴리가 없죠!
    ### Do we *new* the *HeroService*? No way!
  
    `new` 를 통해 `HeroService`의 새로운 인스턴스를 만들 수도 있습니다.
  
    We could create a new instance  of the `HeroService` with `new` like this:
  +makeExample('toh-4/ts/app/app.component.1.ts', 'new-service')(format=".")
  :marked
    이것은 몇 가지 이유에서 안 좋은 생각입니다.
  
    That's a bad idea for several reasons including
  
    * 컴포넌트에서 `HeroService`를 어떻게 만들어야 하는지 알아야 합니다.
    만약 `HeroService` 생성자를 변경해야 한다면,
    서비스를 만드는 모든 부분을 찾아서 수정해야 합니다.
    패치 부분의 코드를 실행하면 에러가 발생하기 쉽고 테스트 부담이 추가됩니다.
  
    * Our component has to know how to create a `HeroService`. 
    If we ever change the `HeroService` constructor, 
    we'll have to find every place we create the service and fix it.
    Running around patching code is error prone and adds to the test burden.
  
    * `new`로 서비스를 생성할 때마다 서비스가 생성됩니다.
    만약 히어로를 캐시하고 그 캐시 정보를 다른 부분에 공유하려고 한다면?
    지금은 그렇게 할 수가 없습니다.
  
    * We create a new service each time we use `new`. 
    What if the service should cache heroes and share that cache with others?
    We couldn't do that.
  
    * `AppComponent`는 `HeroService`라는 특정 구현에 갖혀진 상태입니다.
    다른 시나리오를 고려하여 구현을 변경하기가 어렵습니다.
    오프라인으로 구동할 수는 있을까요?
    테스트 시에는 다른 샘플 버전을 사용할 수 있을까요?
    쉽지 않습니다.
  
    * We're locking the `AppComponent` into a specific implementation of the `HeroService`.
    It will be hard to switch implementations for different scenarios.
    Can we operate offline? 
    Will we need different mocked versions under test?
    Not easy.
  
    *만약 ... 만약 ... 여보세요. 해야 할 것이 많습니다!*
  
    *What if ... what if ... Hey, we've got work to do!*
  
    알겠어요. 실제로 그렇습니다.
    그러나 특별한 이유가 없다면 이러한 문제를 피하는 것이 훨씬 편할 것입니다.
  
    We get it. Really we do. 
    But it is so ridiculously easy to avoid these problems that there is no excuse for doing it wrong.
  
    ### *HeroService* 주입하기
    ### Inject the *HeroService*
  
    *new*로 생성한 한줄을 두줄로 치환합니다:
    1. private 프로퍼티를 정의하는 생성자를 추가합니다.
    1. 컴포넌트의 `providers` 메타데이터에 추가합니다.
  
    Two lines replace the one line that created with *new*:
    1. We add a constructor that also defines a private property.
    1. We add to the component's `providers` metadata.
  :marked
    생성자 자체는 아무것도 하지 않습니다. 파라미터는 private `heroService`  프로퍼티를 정의함과 동시에
    `HeroService` 주입 위치로 확인 됩니다.
  
    The constructor itself does nothing. The parameter simultaneously 
    defines a private `heroService` property and identifies it as a `HeroService` injection site.
  :marked
    이제 Angular는 `AppComponent`를 새로 만들때 `HeroService`의 인스턴스를 제공하게 됩니다.
  
    Now Angular will know to supply an instance of the `HeroService` when it creates a new `AppComponent`. 
  
  .l-sub-section
    :marked
      의존성 주입에 대해 [Dependency Injection](../guide/dependency-injection.html) 에서 더 자세하게 알아보세요.
  
      Learn more about Dependency Injection in the [Dependency Injection](../guide/dependency-injection.html) chapter.
  :marked
    아직 *인젝터*는 어떻게 `HeroService`를 만드는지 알지 못합니다.
    만약 지금 코드를 실행하면, Angular는 아래 에러와 함께 실패할 것입니다.
  
    The *injector* does not know yet how to create a `HeroService`. 
    If we ran our code now, Angular would fail with an error:
  code-example(format="nocode").
      EXCEPTION: No provider for HeroService! (AppComponent -> HeroService)
  :marked
    `HeroService`의 **provider**를 등록하여, *인젝터*에게 `HeroService`를 만드는 방법을 알려줘야 합니다.
    `@Component`를 정의할 때 메타데이터 끝 부분에 아래 `providers` 배열을 추가하면 됩니다.
  
    We have to teach the *injector* how to make a `HeroService` by registering a `HeroService` **provider**.
    Do that by adding the following `providers` array property to the bottom of the component metadata
    in the `@Component` call.
  
  +makeExcerpt('toh-4/ts/app/app.component.1.ts', 'providers')
  :marked
    `providers` 배열은 Angular 에게 `AppComponent`를 생성 시 새로운 `HeroService` 인스턴스를 요청합니다.
    `AppComponent`가 히어로를 얻기 위해 이 서비스를 사용할 수 있고, 컴포넌트 트리의 하위에 있는 모든 컴포넌트에서도 사용할 수 있습니다.
  
    The `providers` array  tells Angular to create a fresh instance of the `HeroService` when it creates a new `AppComponent`.
    The `AppComponent` can use that service to get heroes and so can every child component of its component tree.
  a#child-component
  :marked
    ### *AppComponent* 의 *getHeroes* 메소드
    ### *getHeroes* in the *AppComponent*
  
    `heroService`라는 private 변수로 서비스를 만들었습니다. 이것을 사용해보겠습니다.
  
    We've got the service in a `heroService` private variable. Let's use it.
  
    잠시만 생각해보겠습니다. 서비스를 호출하고 데이터를 가져오는 것을 한 줄에 할 수 있습니다.
  
    We pause to think. We can call the service and get the data in one line.
  +makeExample('toh-4/ts/app/app.component.1.ts', 'get-heroes')(format=".")
  :marked
    사실 한줄로 쓰여진 전용의 메소드가 필요하지는 않습니다. 일단 써보겠습니다.
    
    We don't really need a dedicated method to wrap one line.  We write it anyway:
  +makeExcerpt('toh-4/ts/app/app.component.1.ts', 'getHeroes')
  
  <a id="oninit"></a>
  :marked
    ### *ngOnInit* 라이프사이클 훅
    ### The *ngOnInit* Lifecycle Hook
  
    `AppComponent`는 큰 소란 없이 히어로를 가져오고 보여줄 수 있어야 합니다.
    `getHeroes` 메소드는 어디서 호출해야 할까요? 생성자에서 할까요? 절대 그렇게 하면 *안 됩니다*!
  
    `AppComponent` should fetch and display heroes without a fuss.
    Where do we call the `getHeroes` method? In a constructor? We do *not*!
  
    우리는 다년간의 경험과 고생을 통해 생성자에 복잡한 로직을 넣으면 안 된다는 것을 배웠습니다.
    특히 데이터 접근을 위해 서버 호출을 한다거나 하는 것은 제외해야 합니다.
  
    Years of experience and bitter tears have taught us to keep complex logic out of the constructor,
    especially anything that might call a server as a data access method is sure to do.
  
    생성자는 파라미터를 프로퍼티로 연결하는 것과 같은 간단한 초기화를 위한 것입니다.
    무거운 작업을 위한 것이어서는 안됩니다. 테스트로 컴포넌트를 만들었을 경우, 실제 작업이
    이루어 질거라는 &mdash; 서버를 호출 하는 등!의 걱정은 하지 않을 수 있어야 합니다. &mdash; 명시적으로 호출을 지시하는 것이 아니라면요.
  
    The constructor is for simple initializations like wiring constructor parameters to properties.
    It's not for heavy lifting. We should be able to create a component in a test and not worry that it 
    might do real work &mdash; like calling a server!  &mdash; before we tell it to do so.
  
    생성자가 아니라면, 무엇인가는 `getHeroes`를 호출해야 합니다.
  
    If not the constructor, something has to call `getHeroes`.
  
    만약 Angular의 **ngOnInit** *라이프사이클 훅*을 구현하면 Angular가 그것을 호출해줍니다.
    Angular는 컴포넌트의 라이프사이클에서 생성할 때, 변경된 후, 최종 소멸할 때와 같은
    중요한 순간에 진입할 수 있는 여러 인터페이스를 제공합니다.
  
    Angular will call it if we implement the Angular **ngOnInit** *Lifecycle Hook*.
    Angular offers a number of interfaces for tapping into critical moments in the component lifecycle:
    at creation, after each change, and at its eventual destruction.
  
    각각의 인터페이스에 해당하는 메소드가 있습니다.
    컴포넌트에서 메소드를 구현하면, Angular는 적절한 시점에 해당 메소드를 호출해줍니다.
  
    Each interface has a single method. When the component implements that method, Angular calls it at the appropriate time.
  .l-sub-section
    :marked
      라이프사이클 훅에 대해 [Lifecycle Hooks](../guide/lifecycle-hooks.html) 에서 더 자세하게 알아보세요.
  
      Learn more about lifecycle hooks in the [Lifecycle Hooks](../guide/lifecycle-hooks.html) chapter.
  :marked
    여기 `OnInit` 인터페이스의 주요 아웃라인이 있습니다.
  
    Here's the essential outline for the `OnInit` interface:
  +makeExample('toh-4/ts/app/app.component.1.ts', 'on-init', 'app/app.component.ts (ngOnInit stub)')(format=".")
  :marked
    `ngOnInit` 메소드에 초기화 로직을 작성하고 Angular가 적절한 시점에 호출할 수 있도록 합니다.
    우리는 `getHeroes`를 호출하여 초기화 하겠습니다.
   
    We write an `ngOnInit` method with our initialization logic inside and leave it to Angular to call it
    at the right time. In our case, we initialize by calling `getHeroes`.
  +makeExcerpt('toh-4/ts/app/app.component.1.ts', 'ng-on-init')
  :marked
    애플리케이션이 예상대로 동작하고, 히어로 목록을 보여주고 사용자가 히어로 이름을 선택하면
    히어로 상세 뷰를 보여줘야 합니다.
  
    Our application should be running as expected, showing a list of heroes and a hero detail view
    when we click on a hero name.
  
    거의 다 왔습니다. 그런데 뭔가 이상한 부분이 있습니다.
  
    We're getting closer. But something isn't quite right.
  
    <a id="async"></a>
    ## 비동기 서비스와 !{_Promise}
    ## Async Services and !{_Promise}s
  
    `HeroService`는 샘플 히어로 목록을 바로 반환합니다.
    `getHeroes` 함수모양(signature)은 동기 방식입니다.
  
    Our `HeroService` returns a list of mock heroes immediately. 
    Its `getHeroes` signature is synchronous
  +makeExample('toh-4/ts/app/app.component.1.ts', 'get-heroes')(format=".")
  :marked
    히어로를 요청하면 바로 결과를 반환합니다.
  
    Ask for heroes and they are there in the returned result.
  
    언젠가는 원격 서버에서 히어로를 가져올 것입니다. 아직 http 호출을 하지 않았지만 이후 챕터에서는 http로 호출하려고 합니다.
  
    Someday we're going to get heroes from a remote server. We don’t call http yet, but we aspire to in later chapters.
  
    http 호출을 할 경우, 서버의 응답을 기다려야 하는데 브라우저를 중지할 수는 없기 때문에
    UI를 차단하고 싶다고 해도 (그렇게 하면 안되겠지만) 그럴 수는 없습니다.
  
    When we do, we'll have to wait for the server to respond and we won't be able to block the UI while we wait, 
    even if we want to (which we shouldn't) because the browser won't block.
  
    그래서 비동기 기술을 사용해야 합니다. 이것은 `getHeroes` 메소드의 함수모양(signature)을 변경시킬 것입니다.
  
    We'll have to use some kind of asynchronous technique and that will change the signature of our `getHeroes` method.
  
    여기서는 *!{_Promise}s* 를 사용할 것입니다.
  
    We'll use *!{_Promise}s*.
  
    ### 히어로 서비스의 *!{_Promise}*
    ### The Hero Service makes a !{_Promise}  
  
    **!{_Promise}** 는... 결과가 준비되면 나중에 나를 호출해달라는 약속입니다.
    비동기 서비스에게 어떤 작업을 한 뒤에 결과를 콜백 함수에 전달해달라고 요청하는 것입니다.
    (어디선가) 작업을 하고 결국에는 작업 결과나 에러로 지정한 함수를 호출하는 것입니다.
  
    A **!{_Promise}** is ... well it's a promise to call us back later when the results are ready. 
    We ask an asynchronous service to do some work and give it a callback function. 
    It does that work (somewhere) and eventually it calls our function with the results of the work or an error.
  .l-sub-section
    :marked
      여기서는 간략히 설명했습니다. ES2015 Promise에 대해 [여기](http://exploringjs.com/es6/ch_promises.html) 혹은 다른 웹사이트에서 알아보세요.
  
      We are simplifying. Learn about ES2015 Promises [here](http://exploringjs.com/es6/ch_promises.html) and elsewhere on the web.
  :marked
    `getHeroes` 메소드가 !{_Promise}를 반환하도록 `HeroService`를 수정하세요:
  
    Update the `HeroService` with this !{_Promise}-returning `getHeroes` method:
  +makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes', 'app/hero.service.ts (excerpt)')(format=".")
  :marked
    아직 샘플 데이터를 사용합니다. 샘플 히어로를 결과로 반환하는
    **즉시 처리 !{_Promise}**를 사용하여 초고속, 무지연 서버를 시뮬레이션했습니다.
  
    We're still mocking the data. We're simulating the behavior of an ultra-fast, zero-latency server,
    by returning an **immediately resolved !{_Promise}** with our mock heroes as the result.
  
    ### !{_Promise} 처리
    ### Act on the !{_Promise}
  
    `AppComponent`로 돌아와 `getHeroes` 메소드를 보니 여전히 아래처럼 되어 있습니다.
  
    Returning to the `AppComponent` and its `getHeroes` method, we see that it still looks like this:
  +makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app/app.component.ts (getHeroes - old)')(format=".")
  :marked
    `HeroService` 를 변경했으니, 이제 `this.heroes`에 히어로 배열이 아니라 Promise를 할당하겠습니다.
  
    As a result of our change to `HeroService`, we're now setting `this.heroes` to a !{_Promise} rather than an array of heroes. 
  
    약속이 지켜졌을 때의 행동에 대한 구현을 수정해야 합니다.
    약속이 성공적으로 지켜진다면, 화면에 표시할 히어로를 얻을 수 있습니다.
  
    We have to change our implementation to *act on the !{_Promise} when it resolves*.
    When the !{_Promise} resolves successfully, *then* we will have heroes to display.
  
    !{_Promise}의 **then** 메소드 인자로 콜백함수를 전달합니다.
  
    We pass our callback function as an argument to the !{_Promise}'s **then** method:
  +makeExample('toh-4/ts/app/app.component.ts', 'get-heroes', 'app/app.component.ts (getHeroes - revised)')(format=".")
  .l-sub-section
    :marked
      콜백 함수의 [ES2015 화살표 함수](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
      를 사용하면 동일한 함수 표현을 하는 것보다 간결하고 우아하게 처리가 가능합니다.
  
      The [ES2015 arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
      in the callback is more succinct than the equivalent function expression and gracefully handles *this*.
  :marked
    콜백에서는 서비스에서 받은 히어로를 컴포넌트의 `heroes` 프로퍼티에 할당합니다.
    그게 전부입니다!
  
    Our callback sets the component's `heroes` property to the array of heroes returned by the service. That's all there is to it!
  
    앱은 여전히 실행중이고, 여전히 히어로 목록을 보여주고, 여전히 이름을 선택하면 상세 뷰에 반응을 보입니다.
  
    Our app should still be running, still showing a list of heroes, and still
    responding to a name selection with a detail view.
  .l-sub-section
    :marked
      연결 상태가 좋지 않을 경우 앱이 어떻게 보이는지 확인하려면 "[Take it slow](#slow)" 부록에서 확인하세요.
  
      Checkout the "[Take it slow](#slow)" appendix to see what the app might be like with a poor connection.
  :marked
    ### 앱 구조 리뷰
    ### Review the App Structure
  
    이번 챕터에서 좋은 리팩토링을 한 뒤에 아래와 같은 구조가 되었는지 확인해보세요.
  
    Let’s verify that we have the following structure after all of our good refactoring in this chapter:
  
  .filetree
  