---
# System prepended metadata

title: 第三堂：axios 搭配 Async/Await 再進化

---

# 第三堂：axios 搭配 Async/Await 再進化

## 課程大綱

1.  基本 Promise 與 Async/Await 比較
    1. 1 個觀念 - 20min
2. 錯誤管理
    1. 1 個觀念 - 20min
3. axios 搭配  Async/Await 錯誤管理整合
    1. 1 個觀念 - 20min

## 1. 基本 Promise 與 Async/Await 比較

```jsx
// 一個模擬的非同步函式
function fetchData() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("資料已經獲取");
        }, 2000);
    });
}

// 傳統寫法
// 使用 Promise 的 .then() 方法來處理非同步操作
function getDataWithThen() {
    console.log("開始獲取資料...");
    fetchData().then((data) => {
        console.log(data); // 會在 2 秒後輸出 "資料已經獲取"
    });
}

getDataWithThen();

// 使用 Async/Await 的作法
async function getData() {
    console.log("開始獲取資料...");
    const data = await fetchData();
    console.log(data); // 會在 2 秒後輸出 "資料已經獲取"
}

getData();

```

**使用 async await：提升可讀性、減少複雜性**

async/await 是 JavaScript 中用於處理非同步的一種語法糖，讓程式碼更好理解

- **`async`** 關鍵字用於定義一非同步函式，這個函式將回傳一個 Promise
- 在 **`async`** 函式內部，可以使用 **`await`** 關鍵字來等待一個 Promise 被解析（resolved）。
- async 函式內部可以使用 [`await`](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/await) ，他可以讓程式碼看起來像同步的，它會暫停此 async 函式的執行，並且等待解析，解析完之後會回傳解析值，並繼續此 async 函式的執行。

### axios 寫法如下

```jsx
// 傳統 axios 寫法
const api_path = "自訂路徑"; 

// GET
****const getProductList = () => {
  axios.get(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/products`)
    .then(response **=> {**
	     console.log(response.data.products);
    })
    
};

// POST
function addCartItem(id){
  axios.post(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/carts`,{
    data: {
      productId: id,
      quantity: 1
    }
  }).
    then(function (response) {
      alert("加入購物車成功");
      
    })

}

// async / await 寫法
**// GET
const getProductList = async () => {**
    const response = **await** axios.get(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/products`);
**};

// POST
const addCartItem = async (id) => {
    const response = await axios.post(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/carts`, {
        data: {
            productId: id,
            quantity: 1
        }
    });

    
    alert("加入購物車成功");
};**
```

## 2. 錯誤處理

- [JS error 介紹](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error)、[常見錯誤種類](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#error_types)
- [axios 自訂錯誤物件](https://github.com/axios/axios/blob/main/lib/core/AxiosError.js)
- try catch 可處理
    - 程式錯誤
    - 自訂錯誤 (例：axios 的 promise catch 自訂錯誤、開發者自訂錯誤)

```jsx
// 自訂錯誤
const a = new Error("姓名欄位沒有填寫")
[a.name](http://a.name/) = "驗證失敗"

try{
    throw a;
}catch(error){

    console.log(error)
}

// SyntaxError 錯誤

try {
    // 缺少閉合括號
    let x = (10 + 5;
} catch (error) {
    console.error(`${error.name}: ${error.message}`);
}

// ReferenceError 引用了一個不存在的變數
try {
    console.log(nonExistentVariable); // 變數未定義
} catch (error) {
    console.error(`${error.name}: ${error.message}`);
}
```

### 3. axios 搭配  Async/Await 錯誤管理整合

```jsx
// async / await 寫法
// GET
const api_path = "自訂路徑";
const getProductList = async () => {
    try {
        const response = await axios.get(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/products`);
        console.log(response)
    } catch (error) {
        console.error("取得產品列表失敗", error.response.data);
        alert("取得產品列表時發生錯誤，請稍後再試。");
    }
};

// POST
const addCartItem = async (id) => {
    try {
        const response = await axios.post(`https://livejs-api.hexschool.io/api/livejs/v1/customer/${api_path}/carts`, {
            data: {
                productId: id,
                quantity: 1
            }
        });

        console.log(response)
        alert("加入購物車成功");
    } catch (error) {
        console.error("加入購物車失敗", error.response.data);
        alert("加入購物車時發生錯誤，請稍後再試。");
    }
};
```

