iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0

本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/8 已更新。

寫 ES5 時,只要需要寫到非同步請求,我們或多或少都有接觸到 promise 的寫法。但是因為在 Javascript 中還沒有實作,所以還要額外匯入支援的函式庫或模組,像是 jQueryBlueBird等。

ES2015 中,Promise 終於被納入標準。一直到現在,Promise 已經成為實作非同步方法中的基本方式。在 Fetch APIService Worker 等,主要也是以 Promise 實現非同步行為。所以今天就來好好認識吧!

Imgur

當建立Promise物件時,內部會有一個狀態機制,紀錄目前的執行狀況。主要的狀態有以下幾種-

  • pending:執行傳入Promise物件的非同步操作,呈現「擱置中」的狀態。
  • settled:執行結束後,透過呼叫Promise內建的函式參數,呈現「已解決」的狀態。其中,執行結果的成功與否,可以再分成以下兩種狀態-
    • fulfilled:表示執行結果正常,或是操作成功,呈現「已實現」的狀態。
    • rejected:表示執行結果在意料之外,或操作失敗,呈現「已拒絕」的狀態。

看個基本例子。

// 一秒後隨機取數,如果是偶數就會該數字,如果不是就回QQ
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    const n = Math.floor(Math.random() * 100);
    console.log(n);
    if (n % 2 == 0) resolve(n);
    else reject("QQ");
  }, 1000);
}).catch((err) => {
  console.error(err);
});

// 57
// catch: QQ
// finally done!
// ---or---
// 22
// finally done!

Promise.all(promises)

同時完成多個 Promise。如果任務結束,且都無意外錯誤,就會執行then();反之則執行catch()處理錯誤。

const f1 = fetch("/a.json");
const f2 = fetch("/b.json");
Promise.all([f1, f2])
  .then(([r1, r2]) => {
    console.log("jsons:", r1, r2);
    // jsons: {...} {...}
  })
  .catch((err) => {
    console.error(err);
  });

Promise.race(promises)

如同字面上意思,同時執行多個 Promise,只要最先完成 resolve 的,就會以這個 resolve 的結果執行 then()

const p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 200, "p1");
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 300, "p2");
});
Promise.race([p1, p2]).then((result) => {
  console.log(result); // p1
});

上一篇
ES2015(ES6) - Iterable、Iterator、Generator
下一篇
ES2015(ES6) - ESM模組
系列文
從ES到ESNext - 30天輕鬆掌握ECMAScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言