---
# System prepended metadata

title: Web企業運算_Week10_許家維

---

# Web企業運算_Week10_許家維

### 學習清單
1.上課內容觀念複習(callback,promise...etc)
2.履歷修改
3.技術文件閱讀
學習資料
Promise 教學文件 : https://developers.google.com/web/fundamentals/primers/promises?fbclid=IwAR2yQZo71z1ACmTU8zG7XvHo7PesmAdMT0mSaoIhDcofOegNR0qgPfBYfYo
本篇文章連結 :
https://hackmd.io/kInBHUu1TZKyt-W5qXu3Gw?both
### Code
app.module.ts
```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
<!-- 使用httpclient模組 -->
import { HttpClientModule } from '@angular/common/http'; 

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    <!-- import模組 -->
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```
app.component.ts
```
import { Component } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; 

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'HttpApp';
  data: any;
  // inject object
  constructor(private http:HttpClient){
    <!--   抓取資料   -->
    this.http.get('http://jsonplaceholder.typicode.com/posts').toPromise()
      <!--    渲染出資料    -->
      .then(data=>{console.log(data); this.data = data;})
      <!--    若錯誤    -->
      .catch(err=> console.log(err));
  }
}
```
app.component.html
```
<h1>抓取網路Api資料</h1>
<!-- 遍歷所有的data 給一個變數d -->
<ul *ngFor = "let d of data">
  <!--  依據資料格式顯示出來  -->
  <li>使用者序號:{{d.userId}}</li>
  <li>標題:{{d.title}}</li>
  <li>內容:{{d.body}}</li>
</ul>
```
稍做一點美觀後...
![](https://i.imgur.com/iWcYc16.png)
資料成功抓進來了 !!



### 成果
#### Asynchronous Programming 非同步程式設計
**1. CallBack 回調**
是一個可以作為傳入參數的函式，用於在目前的函式呼叫執行最後移交控制權，而不使用函式回傳值的方式。
直接風格
```
function func(x) { return x }
```
Callback寫法
```
function func(x, cb) { cb(x) }
```
異步回調函式種類通常有 :
* 使用計時器(timer)函式: setTimeout, setInterval
* 特殊的函式: nextTick, setImmediate
* 執行I/O: 監聽網路、資料庫查詢或讀寫外部資源
* 訂閱事件
* 範例
    ```
    function aFunc(value, callback){
      callback(value)
    }

    <!--   即使設定為0ms,裡面的回調函式並不是立即執行，而是會暫緩(延時)執行  -->
    function bFunc(value, callback){
      setTimeout(callback, 0, value)
    }

    function cb1(value){ console.log(value) }
    function cb2(value){ console.log(value) }
    function cb3(value){ console.log(value) }
    function cb4(value){ console.log(value) }

    aFunc(1, cb1)
    bFunc(2, cb2)
    aFunc(3, cb3)
    bFunc(4, cb4)
    <!--   執行順序 1>3>2>4   -->
    ```
**2. Promise**
Why Promise ?
JavaScript 是屬於同步的程式語言，因此一次僅能做一件事情，但遇到非同步的事件時，就會將非同步的事件移動到程式碼的最後方，等到所有的原始碼運行完以後才會執行非同步的事件。
* 概念圖解
![](https://i.imgur.com/nND8fNR.png)
* **Promise 一個特點在於 then、catch 都可以使用鏈接的方式不斷的進行下一個任務，在此範例中我們修改 Promise 的結果，改成傳入 0 則會調用 reject，其它數值則會調用 resolve**
    ```
    function promise(num) {
      return new Promise((resolve, reject) => {
        num ? resolve(`${num}, 成功`) : reject('失敗');
      });
    }
    ```
Promise API
* all -> 多個 Promise 行為同時執行，全部完成後統一回傳
* race -> 多個 Promise 同時執行，但僅回傳單一結果
* Promise.reject, Promise.resolve -> 直接定義 Promise 物件已經完成的狀態（resolve, reject），與 new Promise 一樣會產生一個新的 Promise 物件，但其結果是已經確定的

**3. Observable 可觀察物件 based on Angular**
支援在應用中的發佈者和訂閱者之間傳遞訊息。 在需要進行事件處理、非同步程式設計和處理多個值的時候，可觀察物件相對其它技術有著顯著的優點。
基本用法
**要執行所建立的可觀察物件，並開始從中接收通知，你就要呼叫它的 subscribe() 方法，並傳入一個觀察者（observer）。 這是一個 JavaScript 物件，它定義了你收到的這些訊息的處理器（handler）**
下面的例子會建立並訂閱一個簡單的可觀察物件，它的觀察者會把接收到的訊息記錄到控制檯中
```
// Create simple observable that emits three values
const myObservable = of(1, 2, 3);

// Create observer object
const myObserver = {
  <!-- next:用來處理每個送達值。在開始執行後可能執行零次或多次 -->
  
  next: x => console.log('Observer got a next value: ' + x),
  
  <!-- error:用來處理錯誤通知。錯誤會中斷這個可觀察物件實例的執行過程 -->
  
  error: err => console.error('Observer got an error: ' + err),
  
  <!-- complete:處理執行完畢通知。當執行完畢後，這些值就會繼續傳給下一個處理器 -->
  complete: () => console.log('Observer got a complete notification'),
};

// Execute with the observer object
myObservable.subscribe(myObserver);
// Logs:
// Observer got a next value: 1
// Observer got a next value: 2
// Observer got a next value: 3
// Observer got a complete notification
```
**4. RxJS 函式庫**
RxJS（響應式擴充套件的 JavaScript 版）是一個使用可觀察物件進行響應式程式設計的函式庫，它讓組合非同步程式碼和基於回調(Callback)的程式碼變得更簡單
**RxJS 提供了一種對 Observable 型別的實現**，直到 Observable 成為了 JavaScript 語言的一部分並且瀏覽器支援它之前，它都是必要的。這個函式庫還提供了一些工具函式，用於建立和使用可觀察物件。這些工具函式可用於：
* 把現有的非同步程式碼轉換成可觀察物件
* 迭代流中的各個值
* 把這些值對映成其它型別
* 對流進行過濾
* 組合多個流

RxJS 提供了一些用來建立可觀察物件的函式。這些函式可以簡化根據某些東西建立可觀察物件的過程，比如事件、定時器、承諾等等。比如：
```
<!-- 利用rx.js 建立一個promise 的可觀察物件 -->
import { from } from 'rxjs';

// Create an Observable out of a promise
    
const data = from(fetch('/api/endpoint'));
    
// Subscribe to begin listening for async result
data.subscribe({
     next(response) { console.log(response); },
     error(err) { console.error('Error: ' + err); },
     complete() { console.log('Completed'); }
});
```
**5. Async & Await**
在 ES7 裡頭 async 的本質是 promise 的語法糖，**只要 function 標記為 async，就表示裡頭可以撰寫 await 的同步語法**。await 顧名思義就是「等待」，它會確保一個 promise 物件都解決 ( resolve ) 或出錯 ( reject ) 後才會進行下一步，當 async function 的內容全都結束後，會返回一個 promise，這表示後方可以使用.then語法來做連接
```
~async function {           // ~ 開頭表示直接執行這個 function，結尾有 ()
  const delay = (s) => {
    return new Promise(function(resolve){  // 回傳一個 promise
      setTimeout(resolve,s);               // 等待多少秒之後 resolve()
    });
  };

  console.log(1);      // 顯示 1
  await delay(1000);   // 延遲ㄧ秒
  console.log(2);      // 顯示 2
  await delay(2000);   // 延遲二秒
  console.log(3);      // 顯示 3
}();
```



**6. HttpClient**
大多數前端應用都需要透過 HTTP 協議與後端伺服器通訊。現代瀏覽器支援使用兩種不同的 API 發起 HTTP 請求：**XMLHttpRequest 介面和 fetch() API。**
@angular/common/http 中的 HttpClient 類別為 Angular 應用程式提供了一個簡化的 API 來實現 HTTP 客戶端功能。它基於瀏覽器提供的 XMLHttpRequest 介面
引入語法 : ```import { HttpClientModule } from '@angular/common/http'; ```
再來，將 HttpClient 注入到應用類別
```
@Injectable()
export class ConfigService {
  <!-- 建構子，定義 Property 的初始值 -->
  constructor(private http: HttpClient) { }
}
```






### 心得
這週首先複習了上上周學的Promise概念，透過練習又學了一些技巧。也把callback、es7的async與await等觀念了解的更加清楚。未來會多看一些非同步處理的實務範例，未來希望能夠運用於專案上。Angular的架構，透過許多個禮拜的練習，也漸漸的熟悉起來，或許有時間可以自己製作一個side project吧!另外這週也上了angular的httpcilent模組，能夠透過網路上的API抓取資料並顯示在螢幕上。這部分在VUE有接觸一些，但還不是特別熟悉，會再努力練習這部分(包含資料的預先整理、清洗等...)