---
# System prepended metadata

title: Web企業運算_Week9_許家維

---

# Web企業運算_Week9_許家維

### 學習清單
1. Typescript 基礎練習<br>參考文章 : https://ithelp.ithome.com.tw/articles/10214714
2. Promise 用法練習
3. JS 基本型別複習
4. Canvas 詳細功能複習(專案需求)
5. HackMD 連結 : https://hackmd.io/S1Bls2JkSQG4Yz_dW5CcRQ?both

### Code
**姓名速配指數**
app.components.html
```
<div class="card">
  <h1>姓名配對指數</h1>
  <h4>輸入雙方姓名即可測試</h4>
  A : <input type="text" [(ngModel)] = name1 placeholder="名字1">
  <br>
  B : <input type="text" [(ngModel)] = name2 placeholder="名字2">
  <br>
  {{name1}} 和 {{name2}}  他們的配對指數為 {{score}} 分ㄛ❤❤❤❤
</div>
<router-outlet></router-outlet>
```
style.css
```
* {
    font-family: 微軟正黑體;
    background-color: rgba(0, 0, 0, .2)
}


.card {
    text-align: center;
    /* border : solid 1px black; */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    padding: 50px 120px;
    border-radius: 10px;
    background-color: rgba(255,255,255,.5);
    color: #ed2553;
}

.card > * {
    background-color: transparent;
}

input {
    padding: 5px;
    border : solid 1px #ed2553;
    background-color: rgba(255,255,255,.5);
    color: #ed2553;
    margin-bottom: 25px;
}
```
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';
<!-- 原有框架上新增form模組 -->
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    <!--  import 模組    -->
    FormsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

app.components.ts
```
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'ng2';
<!--  name1 name2 雙向綁定至畫面上  -->
  name1 = '';
  name2 = '';
<!--  建立並初始化物件  -->
  constructor() {

  }
<!--  簡單的計算姓名指數演算法  -->
  get score() {
  <!--  轉成全英文小寫字母 -->
    let letters = (this.name1+this.name2).toLowerCase();
    let sum = 0;
    for(let i=0; i< letters.length;i++){
    <!--  返回0到65535之間的整數(utf-16code)  -->
      sum+=letters.charCodeAt(i);
    }
    return (sum % 101);
  }
}
```
完工畫面
![](https://i.imgur.com/bhxqUlC.png)



### 成果
**TypeScript**
* 由 Microsoft 推出，擁有型別系統（Type System）與介面（Interface）設計的語言，TypeScript 可以想成他是在原生 JS 上包裝上一層新的語法
* 優勢：型別系統 Type System
    * 藉由 TypeScript 在 IDE 上的 Autocomplete Feature 來協助開發並且防止錯誤
    * ![](https://i.imgur.com/T6OZSFQ.png)
    * 可自由設定讓專案編譯成我們想要的 JS 版本(ES5、ES6...)
* ```npm install typescript -g ``` : 下載typescript 指令工具 (要在有Node的環境下)
* ```$ tsc --init ``` : 此時你的專案會出現一個名為 tsconfig.json 的檔案(TS設定檔)
* ```$ tsc file.ts ``` : 將ts檔轉成ES5(預設)的js檔
* ```$ tsc –p src –w ``` : 存檔時可直接將所有資料夾內的ts檔編譯成js檔
* TS 型別
    * 原始型別 ：包含 number, string, boolean, undefined, null, ES6的symbol、void
    * 物件型別 : 
        * 基礎物件型別：包含 JSON 物件，陣列（Array或T[]），類別以及類別產出的物件（也就是 Class 以及藉由 Class new 出來的 Instance）
        * TypeScript 擴充型別：即 Enum 與 Tuple，內建在 TypeScript
        * 函式型別 Function Types：類似於 (input) => (Ouput) 這種格式的型別，後面會再多做說明
    * 明文型別 : 一個值本身也可以成為一個型別，比如字串 "Hello world"
    * 特殊型別 : any、never（TS 2.0）、unknown（TS 3.0）..
    * 複合型別 : union 、 intersection
* Getter : get()，用來取得指定屬性的值，不接受參數
* Setter : set()，設定指定屬性的值，可以有一個參數
* 範例
```
object = {
  a:7,
  get b() { return this.a+1; },
  set c(x) { this.a = x/2; }
};
```

**Promise 概念**
* 建立Promise : ```var promise = new Promise ( (resolve, reject) => { ... } )```
    1. 在建構函式傳入 executor 函式
    2. 可在函式中執行非同步作業
    3. 順利完成時，**呼叫resolved(value)回應所得資料**<br>Value 通常為一合法 Javasript值<br>此時，**進入Fulfilled(已實現)狀態**
    4. 發生錯誤時，**呼叫reject(reason)回應錯誤資訊**<br>reason通常為error物件<br>此時，**進入Reject(拒絕)狀態**
* 可使用 **then** 獲得最終處理結果及進行接續行為
* EX.```var newPromise = promise.then( onFulfilled, onRejected )```
* ```onFulfilled = (value) => {...}```
    * 在 Promise 的 executor 中呼叫 **resolve** 方法會進入此方法中(狀態Fulfilled已實現時)
    * 傳入值
        * 由上層 executor 透過 resolved(value) 傳入的資料
        * 從上層 onFulfilled 或 onRejected 方法直接 return value
        * 不區分值是從 onFulfilled 還是 onRejected 傳出來 (**因在 onFulfilled 或 onRejected 不發生錯誤 / 不呼叫 reject 時，都會進入下個 onFulfilled 中**，當然也包括回傳值)
    * 回傳值
        * value 值 (可以從新Promise 物件 then 中 onFulfilled 方法參數中取得)
        * Promise 物件 : 當有需要再處理一個非同步作業時使用<br>**自己建立一個 Promise 取代 then 回傳的新 Promise 物件value**
        * thenable 物件
* ```onRejected = (reason) => {...}```
    * 在 Promise 的 executor 中呼叫 **reject**方法會進入此方法中
    * 傳入值：
        * 上層 executor 透過 reject(reason) 傳入的錯誤發生資訊
        * 從上層 onFulfilled 或 onRejected 方法直接呼叫 Promise.reject(reason) 
    * 回傳值：value, promise 或 thenable ....etc
    * 多數使用情境下在 then 中只會定義 onFulfilled 方法 
    * 錯誤多會交由 promse.catch 作攔截處置
    
現在來看一個簡單的範例
```
// promise 成功要執行的方法
function onFulfilled (value) {
  console.log(value)  // 'success'
}

// promise 失敗要執行的方法
function onRejected (reason) {
  console.log(reason.message)  // 'wrong !!'
}

// then 處置 promise 成功或失敗要做的事情
doSomethingAsync()
  .then(onFulfilled, onRejected) 

// 通常不特別在 then 中定義 onRejected 方法
// 多數使用 catch 直接捕捉/處理上方連鎖發生的錯誤   
doSomethingAsync()
  .then(onFulfilled) 
  .catch(onRejected) // 等同 then(undefined, onRejected)
```

* ```Promise.all( [promise1, promise2 ....] ).then(onFulfilled). catch(onReject)```
    * 所有 promise 都 resolve 後才會進入 onFulfilled
    * onFulfilled 中傳入的 value 為**陣列格式**，**保存各 promise 回傳的值**
    * **陣列順序與執行順序無關**
    * 所有 promise 其中任一發生錯誤或 reject 情況則馬上回傳
* 直接建立具狀態的promise物件
    * ```Promise.resolve(value).then(onFulfilled, onRejected)```
    * ```Promise.reject(reason).then(onFulfilled, onRejected)```
    * 



### 心得

這週上的觀念比較多，包含非常重要的Promise及A與ngular 搭配的Typescript兩大觀念。目前先對於這兩個大觀念做一個基礎的複習，後面幾周會再多練習幾次，直到熟悉觀念為止。自己的Javascript沒有學的特別好，所以最近花的時間多在JS的基礎型別、Function觀念等等，希望可以透過練習慢慢補強自己較弱的JS部分。