Successfully reported this slideshow.
Your SlideShare is downloading. ×

6. 非同步設計

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
並行、平行與非同步
並行、平行與非同步
Loading in …3
×

Check these out next

1 of 47 Ad
Advertisement

More Related Content

Slideshows for you (20)

Similar to 6. 非同步設計 (20)

Advertisement

Recently uploaded (20)

Advertisement

6. 非同步設計

  1. 1. 6. 非同步設計 • 學習目標 – 區別同步與非同步 – 運用Promise API – 善用async、await – 認識for-await-of – 使用非同步產生器函式 2
  2. 2. 初識非同步 • 龜兔賽跑 3
  3. 3. 4
  4. 4. 5
  5. 5. 6
  6. 6. 同步?非同步? • 在定義的任務完成之後,才會往下一個運 算式、陳述句或函式執行,這樣的流程稱 為同步 7
  7. 7. • 任務未完成前,就執行了後續的程式流程, 那麼這樣的流程就是非同步的 8
  8. 8. • 獨立於程式主流程的任務、事件生成,以 及處理事件的方式,稱為非同步 • 在瀏覽器的環境時…在Node.js的環境中… 非同步根本上就是與JavaScript息息相關的 議題 9
  9. 9. • 在支援多執行緒的語言中,執行緒是用來 實現非同步的方式之一 • JavaScript本身不支援多執行緒,而且是以 單執行緒方式執行程式碼 • 執行環境會在事件迴圈不斷地檢查事件佇 列當事件發生時,並不是馬上執行指定的 函式 10
  10. 10. • 將事件排入佇列,在迴圈下一輪的檢查時, 才將佇列中事件對應的任務依序執行完成 • 如果某個事件對應的任務執行過久,佇列 中後續事件對應的任務就會被卡住 11
  11. 11. 非同步與回呼 • 對於非同步函式想要取得執行結果,方式 之一是使用回呼函式 12
  12. 12. • 若希望任務完成後,接續地執行下一個非 同步任務時,就會發生回呼函式形成巢狀 結構的問題 13
  13. 13. Promise • 在ES6以後,Promise實例可以作是非同步 函式的傳回值 • Promise實例代表著「承諾」在未來提供 任務執行結果 14
  14. 14. • Promise實例建立後,處於未定 (Pending)狀態 • 若呼叫resolve()函式,表示Promise指 定的任務達成(Fulfilled)狀態 15
  15. 15. • 就程式碼閱讀來說,Promise的撰寫風格 就像是循序的,也避免了回呼地獄的問題 • 順序的保證,僅限於then()指定的任務 16
  16. 16. • 如果指定的任務無法達成,可以使用傳入 的reject函式來否決任務 • 此時Promise就會處於否決(Rejected) 狀態 17
  17. 17. 18
  18. 18. • Promise被否決時,表示任務因為某個錯 誤而無法執行下去,如果想要突顯錯誤處 理的流程,建議使用catch()方法 19
  19. 19. 銜接Promise 20 • API的銜接
  20. 20. • 不在意達成的順序,只要達成的結果 • 未達成的Promise還是會繼續執行,也無 法取得其他有達成任務的Promise之結果 21
  21. 21. • 任一個先達成或否決的話,就會當成 Promise.race()傳回的Promise達成或 否決的結果 • 其他Promise還是會繼續執行 22
  22. 22. • 如果想指定一組Promise,並且在全部的 Promise達成或否決之後,再來判斷各個 Promise的狀態? • ES11有個Promise.allSettled() 23
  23. 23. 24
  24. 24. Promise與產生器 25
  25. 25. 26
  26. 26. async函式 • 用來標示函式執行時是非同步 • 呼叫async函式,會傳回Promise物件 27
  27. 27. • 可用來銜接傳回Promise的非同步函式 28
  28. 28. • 如果async函式執行之後無法達成任務, 可以使用throw 29
  29. 29. await與Promise • 若想等待async函式執行完後,再執行後 續的流程,可以使用await 30
  30. 30. • await必須撰寫在async函式之中 • await可以接上任何值,不一定要搭配 async函式 • 若是接上Promise實例,會在任務達成時, 取得達成值作為await的結果 31
  31. 31. 32
  32. 32. • await時底層的事件迴圈並沒有被阻斷 33
  33. 33. • 模擬sleep()的功能 34
  34. 34. • 並不是有了async、await,就不需要 Promise了 35
  35. 35. for-await-of • 迭代處理一組Promise 36
  36. 36. • for..of迴圈並不會等待目前Promise達 成才迭代下一個 • ES9新增了for-await-of語法 37
  37. 37. • 有個產生器函式,每次迭代時都會傳回 Promise 38
  38. 38. 39
  39. 39. 非同步產生器函式 40
  40. 40. Symbol.asyncIterator • 非同步產生器函式傳回的物件,是 AsyncGenerator的實例 • 每次呼叫next()傳回的是Promise • 在任務達成後,取得的物件具有value與 done特性 41
  41. 41. 42
  42. 42. • 非同步產生器函式傳回的非同步產生器, 不具有Symbol.iterator協定,因此不 能使用for..of迭代 • 然而該物件具有 Symbol.asyncIterator協定,可以結 合for-await-of進行迭代 43
  43. 43. 44
  44. 44. 45
  45. 45. 46
  46. 46. • for-await-of也接受Symbol.iterator • for-await-of也可以當成for..of迴圈 • 建議只在被迭代的物件為Promise時,才使 用for-await-of,而不是取代for..of 47

×