anchor.diff:    :marked
       The only obvious difference is that we call `then` on the returned promise instead of `subscribe`.
       We give both methods the same functional arguments. 
  +    
  +    唯一一个比较明显的不同点是我们调用这个返回的承诺的`then`方法，而不再是`subscribe`。
  +    而且我们给了这两个方法完全相同的调用参数。
     .l-sub-section
       :marked
         The less obvious but critical difference is that these two methods return very different results!
  +      
  +      细微却又关键的不同点是，这两个方法返回了非常不同的结果！
   
         The promise-based `then` returns another promise. We can keep chaining more `then` and `catch` calls, getting a new promise each time.
  +      
  +      基于承诺的`then`返回了另一个承诺。我们可以链式调用多个`then`和`catch`方法，每次都返回一个新的承诺。
   
         The `subscribe` method returns a `Subscription`. A `Subscription` is not another `Observable`. 
         It's the end of the line for observables. We can't call `map` on it or call `subscribe` again.
         The `Subscription` object has a different purpose, signified by its primary method, `unsubscribe`.
  +      
  +      但`subscribe`方法返回一个`Subscription`对象。但`Subscription`不是另一个`Observable`。
  +      它是可观察对象的末端。我们不能在它上面调用`map`函数或再次调用`subscribe`函数。
  +      `Subscription`对象的设计目的是不同的，这从它的主方法`unsubscribe`就能看出来。
   
         Learn more about observables to understand the implications and consequences of subscriptions.
  +      
  +      请学习更多关于可观察对象的知识，来理解订阅的实现和效果。
   
   h2#cors Cross-origin requests: Wikipedia example
  +h2#cors 跨域请求：Wikipedia范例
   :marked
     We just learned how to make `XMLHttpRequests` using the !{_Angular_Http} service. 
     This is the most common approach for server communication. 
     It doesn't work in all scenarios.
  +  
  +  我们刚刚学习了用!{_Angular_Http}服务发起`XMLHttpRequests`。
  +  这是与服务器通讯时最常用的方法。
  +  但它不适合所有场景。
   
     For security reasons, web browsers block `XHR` calls to a remote server whose origin is different from the origin of the web page.
     The *origin* is the combination of URI scheme, hostname and port number. 
     This is called the [Same-origin Policy](https://en.wikipedia.org/wiki/Same-origin_policy).
  +  
  +  出于安全的考虑，Web浏览器会阻止到与当前页面不“同源”的远端服务器的`XHR`调用。
  +  所谓*源*就是URI的协议(scheme)、主机名(host)和端口号(port)这几部分的组合。
  +  这被称为[同源策略](https://en.wikipedia.org/wiki/Same-origin_policy)。
   
   .l-sub-section
     :marked
       Modern browsers do allow `XHR` requests to servers from a different origin if the server supports the 
       [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) protocol.
       If the server requires user credentials, we'll enable them in the [request headers](#headers).
  +    
  +    在现代浏览器中，如果服务器支持[CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)协议，那么也可以向不同源的服务器发起`XHR`请求。
  +    如果服务器要请求用户凭证，我们就在[请求头](#headers)中启用它们。
   
   :marked
     Some servers do not support CORS but do support an older, read-only alternative called [JSONP](https://en.wikipedia.org/wiki/JSONP).
     Wikipedia is one such server.
  +  
  +  有些服务器不支持CORS，但支持一种老的、只读的（译注：即仅支持GET）替代协议，那就是[JSONP](https://en.wikipedia.org/wiki/JSONP)。
  +  Wikipedia就是一个这样的服务器。
   .l-sub-section
     :marked
       This [StackOverflow answer](http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about/2067584#2067584) covers many details of JSONP.
  +    
  +    这个[StackOverflow上的答案](http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about/2067584#2067584)覆盖了关于JSONP的很多细节。
   :marked
     ### Search wikipedia
  +  ### 搜索Wikipedia
     
     Let's build a simple search that shows suggestions from wikipedia as we type in a text box.
  +  
  +  我们来构建一个简单的搜索程序，当我们在文本框中输入时，它会从Wikipedia中获取并显示建议的词汇列表。
   
   figure.image-display
     img(src='/resources/images/devguide/server-communication/wiki-1.gif' alt="Wikipedia search app (v.1)" width="250")
  
positive.code:     It's an optional service in its own `angular2-in-memory-web-api` library
      that we installed with npm (see `package.json`) and 
      registered for module loading by SystemJS (see `systemjs.config.js`)
  
  :marked
    The in-memory web API gets its data from #{_a_ca_class_with} a `createDb()`
    method that returns a map whose keys are collection names and whose values 
    are #{_array}s of objects in those collections.
    
    Here's the class we created for this sample based on the JSON data:
  +makeExample('server-communication/ts/app/hero-data.ts', null, 'app/hero-data.ts')(format=".")
  :marked
    Ensure that the `HeroService` endpoint refers to the web API:
  +makeExample('server-communication/ts/app/toh/hero.service.ts', 'endpoint')(format=".")
  :marked
    Finally, we need to redirect client HTTP requests to the in-memory web API.
  block redirect-to-web-api
    :marked
      This redirection is easy to configure because Angular's `http` service delegates the client/server communication tasks
      to a helper service called the `XHRBackend`. 
  
      To enable our server simulation, we replace the default `XHRBackend` service with 
      the in-memory web API service using standard Angular provider registration techniques. 
      We initialize the in-memory web API with *seed data* from the mock hero dataset at the same time.
  
  p Here is the revised (and final) version of the #[code #[+adjExPath('app/main.ts')]] demonstrating these steps.
  +makeExample('server-communication/ts/app/main.ts', 'final', 'app/main.ts (final)')(format=".")
  
  p See the full source code in the #[+liveExampleLink2()].
  
negative.code:   :marked
      Back in the `HeroListComponent`, we see that *its* `addHero()` method subscribes to the observable returned by the *service's* `addHero()` method.
      When the data, arrive it pushes the new hero object into its `heroes` array for presentation to the user.
      
      回到`HeroListComponent`，我们看到*该组件的*`addHero()`方法中订阅了这个由*服务中*的`addHero()`方法返回的可观察对象。
      当有数据到来时，它就会把这个新的英雄对象追加(push)到`heroes`数组中，以展现给用户。
  +makeExample('server-communication/ts/app/toh/hero-list.component.ts', 'addHero', 'app/toh/hero-list.component.ts (addHero)')(format=".")
  
  block promises
    h2#promises Fall back to Promises
    h2#promises 退化为承诺(Promise)
    :marked
      Although the Angular `http` client API returns an `Observable<Response>` we can turn it into a 
      [Promise<Response>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) if we prefer.
      It's easy to do and a promise-based version looks much like the observable-based version in simple cases.
      
      虽然Angular的`http`客户端API返回的是`Observable<Response>`类型的对象，但我们也可以把它转成
      [Promise<Response>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。
      这很容易，并且在简单的场景中，一个基于承诺(Promise)的版本看起来很像基于可观察对象(Observable)的版本。
    .l-sub-section
      :marked
        While promises may be more familiar, observables have many advantages. 
        Don't rush to promises until you give observables a chance.
        
        可能“承诺”看起来更熟悉一些，但“可观察对象”有很多优越之处。
        不要匆匆忙忙的就决定用“承诺”，你值得给“可观察对象”一次机会。
    :marked
      Let's rewrite the `HeroService` using promises , highlighting just the parts that are different.
      
      我们来使用承诺重写`HeroService`，要特别注意那些不同的部分。
    +makeTabs(
      'server-communication/ts/app/toh/hero.service.promise.ts,server-communication/ts/app/toh/hero.service.ts', 
      'methods, methods', 
      'app/toh/hero.service.promise.ts (promise-based), app/toh/hero.service.ts (observable-based)')
    :marked
      Converting from an observable to a promise is as simple as calling `toPromise(success, fail)`.
      
      把可观察对象转变成承诺是很简单的，只要调用`toPromise(success, fail)`就行了。
  
      We move the observable's `map` callback to the first *success* parameter and its `catch` callback to the second *fail* parameter
      and we're done!
      Or we can follow the promise `then.catch` pattern as we do in the second `addHero` example.
      
      我们把可观察对象的`map`回调移到第一个*success*参数中，而它的`catch`回调移到第二个*fail*参数中，这就算完工了。
      或者我们可以像第二个`addHero`例子中那样使用承诺的`then.catch`模式。
  
      Our `errorHandler` forwards an error message as a failed promise instead of a failed Observable.
      
      我们的`errorHandler`也改用了一个失败的承诺，而不再是失败的可观察对象。
  
      The diagnostic *log to console* is just one more `then` in the promise chain.
      
      把诊断信息*记录到控制台*也只是在承诺的处理链中多了一个`then`而已。
  
      We have to adjust the calling component to expect a `Promise` instead of an `Observable`.
      
      为了用`Observable`代替`Promise`，我们还得对调用方组件进行调整。
  
    +makeTabs(
      'server-communication/ts/app/toh/hero-list.component.promise.ts, server-communication/ts/app/toh/hero-list.component.ts', 
  