# 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部分。