# 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>
```
稍做一點美觀後...

資料成功抓進來了 !!
### 成果
#### 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 是屬於同步的程式語言,因此一次僅能做一件事情,但遇到非同步的事件時,就會將非同步的事件移動到程式碼的最後方,等到所有的原始碼運行完以後才會執行非同步的事件。
* 概念圖解

* **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有接觸一些,但還不是特別熟悉,會再努力練習這部分(包含資料的預先整理、清洗等...)