anchor.diff:    
     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:
  +  
  +  在真实的世界中，我们并不需要把一行代码包装成一个专门的方法，但无论如何，我们在演示代码中先这么写：
   +makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app.component.ts (getHeroes)')(format=".")
   
   <a id="oninit"></a>
   :marked
     ### The *ngOnInit* Lifecycle Hook
  +  ### *ngOnInit* 生命周期钩子 
     `AppComponent` should fetch and display heroes without a fuss.
     Where do we call the `getHeroes` method? In a constructor? We do *not*!
     
  +  毫无疑问，`AppComponent`应该获取英雄数据并显示它。
  +  我们该在哪里调用`getHeroes`方法呢？在构造函数中吗？ *不* ！
  +  
     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.
  +  
  +  多年的经验和惨痛的教训教育我们，把复杂的逻辑扔到构造函数外面去，特别是那些需要从服务器获取数据的逻辑更是如此。
     
     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.
     
  +  构造函数是为了初始化而设计的，比如把构造函数的参数赋值给属性。
  +  它的负担不是应该过于沉重。我们应该能在测试中创建一个测试，而不用担心它会完成实际的工作 —— 比如和服务器通讯，我们将来才会主动要求它做这些。
  +  
     If not the constructor, something has to call `getHeroes`.
  +  
  +  如果不在构造函数中，总要有地方调用`getHeroes`吧。
     
     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的 **ngOnInit** *生命周期钩子* ，Angular就会调用这个钩子。
  +  Angular提供了一些接口，用来介入组件生命周期的几个关键时间点：刚创建时、每次变化时，以及最终被销毁时。
  +  
     Each interface has a single method. When the component implements that method, Angular calls it at the appropriate time.
  +  
  +  每个接口都是一个单独的方法。只要组件实现了这个方法，Angular就会在合适的时间调用它。
   .l-sub-section
     :marked
       Learn more about lifecycle hooks in the [Lifecycle Hooks](../guide/lifecycle-hooks.html) chapter.
  +    
  +    要了解关于生命周期钩子的更多知识，请参见 [生命周期钩子](../guide/lifecycle-hooks.html) 一章。
   :marked
     Here's the essential outline for the `OnInit` interface:
  -+makeExample('toh-4/ts/app/app.component.1.ts', 'on-init', 'app.component.ts (OnInit protocol)')(format=".")
  +  
  +  这是`OnInit`接口的基本轮廓：
  ++makeExample('toh-4/ts/app/app.component.1.ts', 'on-init', 'app.component.ts (OnInit协议)')(format=".")
   :marked
     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`.
  -+makeExample('toh-4/ts/app/app.component.1.ts', 'ng-on-init', 'app.component.ts (OnInit protocol)')(format=".")
  +  
  +  我们写下带有初始化逻辑的`ngOnInit`方法，然后留给Angular，供其在正确的时刻调用。在这个例子中，我们通过调用`getHeroes`来完成初始化。
  ++makeExample('toh-4/ts/app/app.component.1.ts', 'ng-on-init', 'app.component.ts (OnInit协议)')(format=".")
   :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.
  +  
  +  我们就快完成了，但还有点事不太对劲。
   
     ## Async Services and Promises
  +  ## 异步服务与承诺（Promise）
     Our `HeroService` returns a list of mock heroes immediately. 
     Its `getHeroes` signature is synchronous
  +  
  +  我们的`HeroService`立即返回一个模拟的英雄列表，它的`getHeroes`函数签名是同步的。
   +makeExample('toh-4/ts/app/app.component.1.ts', 'get-heroes')(format=".")
   :marked
     Ask for heroes and they are there in the returned result.
  +  
  +  请求英雄数据，并且直接在结果中返回它。
      
     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，但是我们希望在将来的章节中这么做。
  +  
     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.
     
  +  那时候，我们不得不等待服务器返回，并且在等待时，我们没法停止UI响应，即使我们想这么做，也做不到，因为浏览器不会停止。
  +  
     We'll have to use some kind of asynchronous technique and that will change the signature of our `getHeroes` method.
     
  +  我们不得不使用一些异步技术，而这将改变`getHeroes`方法的签名。
  +  
     We'll use  *promises*.
     
  +  我们将使用 *承诺* 。
  +  
     ### The Hero Service makes a promise  
  +  ### `HeroService`生成一个承诺
   
     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
       We are simplifying. Learn about ES2015 Promises [here](http://exploringjs.com/es6/ch_promises.html) and elsewhere on the web.
  +    
  +    这里只是粗浅的说说，要了解更多，请参见[这里](http://exploringjs.com/es6/ch_promises.html)以及在Web上搜索其他学习资源。
   :marked
     Update the `HeroService` with this promise-returning `getHeroes` method:
  +  
  +  把`HeroService`的`getHeroes`方法改写为返回承诺的形式：
   +makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes', 'hero.service.ts (getHeroes)')(format=".")
   :marked
     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.
     
  +  我们继续使用模拟数据。我们通过返回一个 *立即完成的承诺* 的方式，模拟了一个超快、零延迟的超级服务器。
     ### Act on the Promise
  +  ### 基于承诺的行动
     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.component.ts (getHeroes - old)')(format=".")
  +  
  +  回到`AppComponent`和它的`getHeroes`方法，我们看到它看起来还是像这样的：
  ++makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app.component.ts (getHeroes - 老的)')(format=".")
   :marked
     As a result of our change to `HeroService`, we're now setting `this.heroes` to a promise rather than an array of heroes. 
  +  
  +  作为我们修改`HeroService`的结果，我们正在把`this.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.
     
  +  我们得修改我们的实现，把它变成 *基于承诺* 的，并且在承诺完成时再行动。
  +  一旦承诺成功的完成了，我们就会显示英雄数据。
  +  
     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.component.ts (getHeroes - revised)')(format=".")
  +  
  +  我们把回调函数作为参数传给承诺对象的 **then** 函数：
  ++makeExample('toh-4/ts/app/app.component.ts', 'get-heroes', 'app.component.ts (getHeroes - 修改版)')(format=".")
   .l-sub-section
     :marked
       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*.
  +    
  +    回调中所用的[ES2015箭头函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
  +    能比等价的函数表达式更加简明、优雅的处理 *this* 指针。
   :marked
     Our callback sets the component's `heroes` property to the array of heroes returned by the service. That's all there is to it!
  +  
  +  在回调中，我们把由服务返回的英雄数组赋值给组件的`heroes`属性。是的，这就搞定了。
     
     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
       Checkout the "[Take it slow](#slow)" appendix to see what the app might be like with a poor connection.
  +    
  +    查看附件中的“[慢一点儿](#slow)”一节，以了解在较差的网络连接中这个应用会是什么样的。
   :marked
     ### Review the App Structure
  +  ### 回顾应用结构
     Let’s verify that we have the following structure after all of our good refactoring in this chapter:
  +  
  +  再检查下，经历了本章的所有重构之后，我们应该有了下列文件结构：
   
   .filetree
     .file angular2-tour-of-heroes
  
positive.code:   `)
  :marked
    ## The Road We’ve Travelled
    Let’s take stock of what we’ve built.
  
    * We created a service class that can be shared by many components
    * We used the `ngOnInit` Lifecycle Hook to get our heroes when our `AppComponent` activates
    * We defined our `HeroService` as a provider for our `AppComponent`
    * We created mock hero data and imported them into our service
    * We designed our service to return a promise and our component to get our data from the promise
  
    [Run the live example for part 4](/resources/live-examples/toh-4/ts/plnkr.html)
  
    ### The Road Ahead
    Our Tour of Heroes has become more reusable using shared components and services.
    We want to create a dashboard, add menu links that route between the views, and format data in a template.
    As our app evolves, we’ll learn how to design it to make it easier to grow and maintain.
    
    We learn about Angular Component Router and navigation among the views in the [next tutorial](toh-pt5.html) chapter.
    
  .l-main-section
  <a id="slow"></a>
  :marked
    ### Appendix: Take it slow
    
    We can simulate a slow connection.
    
    Import the `Hero` symbol and add the following `getHeroesSlowly` method to the `HeroService`
  +makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes-slowly', 'hero.service.ts (getHeroesSlowy)')(format=".")
  :marked
    Like `getHeroes`, it also returns a promise. 
    But this promise waits 2 seconds before resolving the promise with mock heroes.
    
    Back in the `AppComponent`, replace `_heroService.getHeroes` with `_heroService.getHeroesSlowly`
    and see how the app behaves.
    
  .l-main-section
  <a id="shadow-provider"></a>
  :marked
    ### Appendix: Shadowing the parent's service
    
    We stated [earlier](#child-component) that if we injected the parent `AppComponent` `HeroService`
    into the `HeroDetailComponent`, *we must not add a providers array* to the `HeroDetailComponent` metadata.
  
    Why?  Because that tells Angular to create a new instance of the `HeroService` at the `HeroDetailComponent` level.
    The `HeroDetailComponent` doesn't want its *own*  service instance; it wants its *parent's* service instance.
    Adding the `providers` array creates a new service instance that shadows the parent instance.
    
    Think carefully about where and when to register a provider. 
    Understand the scope of that registration. Be careful not to create a new service instance at the wrong level.
  
negative.code:   Because data services are invariably asynchronous, 
    we'll finish the chapter with a promise-based version of the data service.
  
    因为数据服务通常都是异步的，所以在本章的最后，我们会把它重构为基于承诺（Promise，一种异步编程模式）的版本。
  :marked
    [Run the live example for part 4](/resources/live-examples/toh-4/ts/plnkr.html)
    
  