非同步api範例 - daniel-qa/Vue GitHub Wiki

非同步api範例

使用 for of (流程控制)

const fillRecipientList = async () => {
  column3Items.value = []; // 清空舊資料(如需)

  for (const item of form.value.searchContent) {
    if (item.mode === "area") {
      // 等待非同步取得學區資料
      const stats = await getAreaStats(item.id);
      column3Items.value.push({
        id: item.id,
        name: item.name,
        scCnt: stats?.scCnt ?? 0,
        tchCnt: stats?.tchCnt ?? 0,
        receiveType: 1,
        showID_Tag: false
      });
    } else if (item.mode === "school") {
      // 同步直接推入
      column3Items.value.push({
        id: item.id,
        name: item.name,
        scCnt: 1,
        tchCnt: item.tchCnt ?? 0,
        receiveType: 2,
        showID_Tag: false
      });
    }
  }

  console.log("所有資料填入完成!");
};

使用 Promise.all (大資料量)

Promise.all 等到所有 Promise 都完成了,才開始執行下一步。

const fillRecipientList = async () => {
  const promises = [];

  form.value.searchContent.forEach(item => {
    if (item.mode === "area") {
      // 非同步取得學區資料
      const p = getAreaStats(item.id).then(stats => {
        column3Items.value.push({
          id: item.id,
          name: item.name,
          scCnt: stats?.scCnt ?? 0,
          tchCnt: stats?.tchCnt ?? 0,
          receiveType: 1,
          showID_Tag: false
        });
      });
      promises.push(p);
    } else if (item.mode === "school") {
      // 直接同步推入學校資料
      column3Items.value.push({
        id: item.id,
        name: item.name,
        scCnt: 1,
        tchCnt: item.tchCnt ?? 0,
        receiveType: 2,
        showID_Tag: false
      });
    }
  });

  await Promise.all(promises);
  // 所有非同步任務完成後,這裡可以做後續處理
  console.log("所有資料填入完成!");
};

說明

.then 與 await

// 傳統寫法
getData().then(res => console.log(res));

// async 寫法
const res = await getData();
console.log(res);

範例對照

  • 使用 .then()
fetch("url")
  .then(res => res.json())
  .then(data => console.log("資料是:", data))
  .catch(err => console.error("錯誤:", err));
  • 使用 await(可讀性更高)
async function loadData() {
  try {
    const res = await fetch("url");
    const data = await res.json();
    console.log("資料是:", data);
  } catch (err) {
    console.error("錯誤:", err);
  }
}

await 是「看起來同步」地呼叫一個非同步函式。

  • await 只能在 async 函式中使用。

  • 若無法將函式改為 async,應使用 .then() 處理 Promise 結果。

  • await和 .then() 功能相同,但語法風格不同。


for of 的用法,差異

需求 用法 特點
需要逐步執行、控制順序 for...of + await ✅ 慢但安全,適合流程控制
要全部並行再一起等 map + Promise.all ⚡ 快,適合查詢大量資料(無順序需求)
千萬不要這樣寫 forEach + async/await ❌ 不會等、不保順序、容易踩坑

for-of 基本語法(for-of statement)

for (const item of iterable) {
  // 執行區塊
}