pcwu's TIL Notes


[JS] Promise.all 筆記

之前筆記過 promise / async / await 現在來筆記一下今天用到的 promise.all

拿之前的例子,這樣執行起來會花費 3 + 5 = 8 秒:

async function wait(i, time = 1000) {
  return new Promise((resolve, reject) => {
    setTimeout(v => resolve(i), time);
  })
}

//pure await
(async function() {
  var res = await wait('wait 3 sec', 3000);
  var res2 = await wait('wait 5 sec', 5000);
  console.log(res, res2);
})()

但如果 resres2 是2個不同的 request 的 response,我們會希望他5秒就結束回傳2個結果了。最好有其中一個失敗時還會 reject 。這時就可以用上 promise.all 了!一個例子:

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([p1, p2, p3]).then(values => {
  console.log(values); // [3, 1337, "foo"]
});

可以看得出來是用一個 array 裝起要集合起來的結果,而且被集合的元素不必是 Promise 甚至不用是 function。

然後有一個 reject 就會整個 reject 了:

var p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
  reject('reject');
});

Promise.all([p1, p2, p3]).then(values => {
  console.log(values);
}, reason => {
  console.log(reason)
});

//From console:
//"reject"

如果搭配 async / await

const getData = async (query) => (
  Promise.all([getDataA(query), getDataB(query)]);
);

// 沒有處理 reject
const showData = async (query) => {
  const data = await getData(query);
  console.log(data); // 會顯示 [dataA, dataB]
};

// 處理 reject
const showData = async (query) => {
  try {
    const data = await getData(query);
    console.log(data); // 會顯示 [dataA, dataB]
  } catch (error) {
    console.log(error); // 會顯示 getDataA 或 getDataA 的 reject reason
  }
};

其實好像還是有些 async / await 細節似懂非懂的,有新的領悟再來修改舊文和新增筆記。

Reference