40
關於 Javascript 非同步的那些事兒 陳小風 @ ModernWeb 2017

關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

關於 Javascript

非同步的那些事兒陳小風 @ ModernWeb 2017

Page 2: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

自我介紹

• 陳鋒逸(陳小風)

• 經歷• 微軟最有價值專家 (MVP)

• SkillTree兼任講師

• 社群研討會講師

• @TechPodcastNight

• twMVC

• AgileCommunity.tw

• Javascript.tw

2

粉絲團: 愛流浪的小風

Page 3: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Agenda

• Javascript 與非同步

• callback vs promise

• genertor 的出現及設計精神

• 使用 async/ await 讓非同步程式更簡潔

Page 4: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Javascript 與非同步

Page 5: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Javascript

• 單執行緒

• 非阻塞式

• 非同步

• Run Everywhere

Page 6: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

單執行緒

• 瀏覽器導向

• 避免複雜性

• 核心特徵

• Html 5 Web Worker

Page 7: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

阻塞…

while(true) {console.log('Looping...')

}

console.log('Finished!') 永遠不會執行

https://codepen.io/kirkchen/pen/eEzVBe?editors=1010#0

Page 8: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Event Loop

STACK WEBAPIS

TASK QUEUE

同步任務

非同步任務

外部 APIDOM

ajax

setTimeout

HEAP

Page 9: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Event Loop

STACK WEBAPIS

TASK QUEUE

console.log('Hello');

setTimeout(function cb(){console.log('2017');

}, 2000);

console.log('ModernWeb')

Console.log

Hello

Page 10: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Event Loop

STACK WEBAPIS

TASK QUEUE

console.log('Hello');

setTimeout(function cb(){console.log('2017');

}, 2000);

console.log('ModernWeb')

setTimeout

Timer

Hello

Page 11: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Event Loop

STACK WEBAPIS

TASK QUEUE

console.log('Hello');

setTimeout(function cb(){console.log('2017');

}, 2000);

console.log('ModernWeb')

console.log

HelloModernWeb

Timer

Page 12: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Event Loop

STACK WEBAPIS

TASK QUEUE

console.log('Hello');

setTimeout(function cb(){console.log('2017');

}, 2000);

console.log('ModernWeb')

HelloModernWeb

Timer21

Function cb

console.log

2017http://latentflip.com/loupe/

Page 13: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

callback vs promise

Page 14: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

What is callback?

設定鬧鐘叫我起床 去睡覺

時間到,鬧鐘響 起床

Page 15: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Callback

• 非同步

• 滿足情境時觸發

• 複雜邏輯不好維護

• 較難處理錯誤

setTimeout(function cb(){

console.log('2017');},2000

);

Page 16: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

What is promise?

想吃雞排 排隊等雞排 終於吃到雞排

等了 30 分鐘,又熱又累…

Page 17: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

What is promise?

想吃雞排 叫學弟去買雞排

吹冷氣、上網 學弟排隊等雞排

學弟買雞排回來開心吃雞排

Page 18: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

What is promise?

呼叫 Api取得資料

發送請求給Server

處理其他事情 等待 Server 回應

Server 回傳資料呈現資料

Promise

取得 Promise

Promise Resolve

Page 19: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Promise

• 兼容性

• 狀態明確

• 可以連續執行

• 更好閱讀

var promise = $.get('http://api.getdata');

promise.then(function success(data) {

console.log(data);},function(err){

console.log(err)}

);

Success

Failure

Page 20: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

genertor 的出現及設計精神

Page 21: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Iterator

• 佔記憶體空間

• 記憶體讀寫花時間

• 處理 10000 個物件

function GetDataList() {var dataList = [];var i = 0;

while (i < 10000) {dataList.push(i);i++;

}

return dataList}var dataList = GetDataList();for(var data of dataList){

console.log(data)}

Page 22: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Generator

• 一次一個

• 停在上次執行之處

• 節省記憶體

function* GetDataList() {var i = 0;

while (i < 100) {yield i;i++;

}}var dataList = GetDataList();console.log(dataList.next().value);console.log(dataList.next().value);console.log(dataList.next().value)

Page 23: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Generator

• 打電動,看攻略

打電動卡關

第一關攻略

上網找攻略

繼續打電動

第二關攻略

暫停

暫停

過關

Page 24: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Generator

• 呼叫 Api

程式啟動

Response

Start Ajax

繼續執行

Start Ajax

yield

yield

執行完畢

Page 25: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Generatorco(function* (){

const a = yield request('api.com/a');const b = yield request('api.com/b');

console.log(a);console.log(b);

})

• 暫時交出執行權

• 封裝非同步任務,處理 Promise

• 邏輯清楚好理解

Page 26: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Generatorco(function* (){

const a = yield request('api.com/a');const b = yield request('api.com/b');

console.log(a);console.log(b);

})

• 讓 Generator 自動執行

• 回傳為 Promise

Page 27: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

使用 async/ await 讓非同步程式更簡潔

Page 28: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

async / await

• 結合 Promise 與 Generator

• 不需要 第三方套件

• 非同步程式同步化

• 直覺化的邏輯思考

• ES7, TypeScript 支援

Page 29: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

async / awaitco(function* (){

const a = yield request('api.com/a');const b = yield request('api.com/b');

console.log(a);console.log(b);

})

Page 30: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

async / awaitasync function Main(){

const a = await request('api.com/a');const b = await request('api.com/b');

console.log(a);console.log(b);

})

Page 31: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

async / await

• async – 標住在 function 前面

• await – 標住在 promise 前面

• 一定要用 function 包裝

• 回傳為 Promise 類型

Page 32: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

回顧

Page 33: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

callbackvar a, b; request('api.com/a', function(err, result){

if(err) { // 錯誤處理

} a = result;

request('api.com/b', function(err, result){ if(err){

// 錯誤處理 } b = result;

console.log(a);console.log(b);

})

}

Page 34: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

promise

var a, b;request('api.com/a').then(function(result){

a = result;}).then(function(){

return request('api.com/b');}).then(function(result){

b = result;

console.log(a);console.log(b);

})

Page 35: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

generatorco(function* (){

const a = yield request('api.com/a');const b = yield request('api.com/b');

console.log(a);console.log(b);

})

Page 36: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

async / awaitasync function Main(){

const a = await request('api.com/a');const b = await request('api.com/b');

console.log(a);console.log(b);

})

Page 37: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

總結

• 善用非同步

• 學習新寫法

• 理解運作機制

• 節省開發時間

Page 38: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

Reference

• Philip Roberts: Help, I’m stuck in an event-loop.

• JavaScript 運行機制詳解:再談Event Loop

• Going Async With ES6 Generators

• JavaScript 非同步程式革命-async、await 與 TypeScript 2.1

Page 39: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

We're Hiring

jobs.kktix.cc

Page 40: 關於 JAVASCRIPT 非同步的那些事兒 公開版™³小風.pdf · 2017. 8. 11. · EventLoop STACK WEBAPIS TASKQUEUE 同步任務 非同步任務 外部API DOM ajax setTimeout

謝 謝 大 家