Frontend Academy · บทเรียน

async/await และการจัดการข้อผิดพลาด

เขียนฟังก์ชัน async ด้วยคีย์เวิร์ด await ครอบการเรียกที่มี await ไว้ในบล็อก try/catch และทำความเข้าใจว่า async/await เป็นรูปแบบไวยากรณ์ที่ช่วยให้ใช้งาน Promise ได้สะดวกขึ้น

บทเรียน 4 จาก 413 ขั้นตอน

async/await และการจัดการข้อผิดพลาด เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

การทำงานแบบอะซิงก์/รอผลคืออะไร

async/await เป็นรูปแบบไวยากรณ์ย่อของพรอมิส ฟังก์ชัน async จะคืนค่าพรอมิสเสมอ คีย์เวิร์ด await จะหยุดฟังก์ชันไว้จนกว่าพรอมิสที่รอจะเข้าสู่สถานะสิ้นสุด โค้ดดูเหมือนทำงานแบบซิงโครนัส แต่จริง ๆ ทำงานแบบอะซิงก์

ฟังก์ชันแบบอะซิงก์

เพิ่มคีย์เวิร์ด async ไว้หน้าประกาศฟังก์ชันหรือนิพจน์ฟังก์ชัน ฟังก์ชันนั้นจะห่อค่าที่คืนไว้ในพรอมิสโดยอัตโนมัติ

async function fetchUser(id) {
  // implicitly returns a Promise
  return { id, name: 'Alice' };
}

// Equivalent to:
function fetchUser(id) {
  return Promise.resolve({ id, name: 'Alice' });
}

การรอพรอมิส

await ใช้ได้เฉพาะภายในฟังก์ชัน async เท่านั้น คีย์เวิร์ดนี้จะหยุดการทำงานไว้จนกว่าพรอมิสจะสำเร็จ แล้วคืนค่าที่แก้ไขแล้ว โค้ดอื่นในลูปเหตุการณ์ยังคงทำงานต่อไป

async function loadProfile(id) {
  const user = await fetchUser(id);     // waits for Promise
  const posts = await fetchPosts(user.id); // waits again
  return { user, posts };
}

การรอแบบต่อเนื่องเทียบกับแบบขนาน

การรอแบบต่อเนื่องอ่านเข้าใจง่าย แต่จะช้าหากงานต่าง ๆ ไม่ได้ขึ้นต่อกัน ใช้ Promise.all() เพื่อรอหลายงานที่เป็นอิสระต่อกันแบบขนาน

// Sequential (slow if tasks are independent):
const user = await fetchUser(id);
const settings = await fetchSettings(id); // waits for user unnecessarily

// Parallel (fast):
const [user, settings] = await Promise.all([
  fetchUser(id),
  fetchSettings(id),
]);

try/catch สำหรับการจัดการข้อผิดพลาด

ห่อการเรียกใช้ที่มีการรอไว้ใน try/catch เพื่อจัดการการปฏิเสธ บล็อก catch จะได้รับเหตุผลของการปฏิเสธเป็นออบเจ็กต์ข้อผิดพลาด

async function saveUser(data) {
  try {
    const response = await fetch('/api/users', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: { 'Content-Type': 'application/json' }
    });
    if (!response.ok) throw new Error(`Server error ${response.status}`);
    return await response.json();
  } catch (err) {
    console.error('Save failed:', err.message);
    throw err; // re-throw so caller can handle
  }
}

การรอระดับบนสุด

ในโมดูล ES (ไม่ใช่ CommonJS) คุณสามารถใช้ await ที่ระดับบนสุดได้โดยไม่ต้องห่อไว้ในฟังก์ชันแบบอะซิงก์ เหมาะสำหรับการเริ่มต้นโมดูล

// module.js (ES module)
const config = await fetch('/config.json').then(r => r.json());
export const API_URL = config.apiUrl;

การทำงานแบบอะซิงก์/รอผลร่วมกับ forEach — จุดที่ควรระวัง

Array.forEach() จะไม่รอฟังก์ชันเรียกกลับแบบอะซิงก์ ใช้การวนซ้ำทีละรายการสำหรับการวนซ้ำแบบอะซิงก์ที่ต่อเนื่องกัน หรือใช้ Promise.all(arr.map(...)) สำหรับการทำงานแบบขนาน

// WRONG — forEach doesn't await:
items.forEach(async (item) => {
  await processItem(item); // runs but forEach doesn't wait
});

// CORRECT — sequential:
for (const item of items) {
  await processItem(item);
}

// CORRECT — parallel:
await Promise.all(items.map(item => processItem(item)));

ออบเจ็กต์ข้อผิดพลาดและข้อผิดพลาดแบบกำหนดเอง

ควรโยนออบเจ็กต์ข้อผิดพลาดเสมอ ไม่ใช่สตริง เพื่อรักษาร่องรอยสแตกไว้ สร้างคลาสข้อผิดพลาดแบบกำหนดเองสำหรับข้อผิดพลาดเฉพาะโดเมน เพื่อให้ผู้เรียกตรวจจับตามชนิดได้

class NetworkError extends Error {
  constructor(message, status) {
    super(message);
    this.name = 'NetworkError';
    this.status = status;
  }
}

try {
  const res = await fetch(url);
  if (!res.ok) throw new NetworkError(`Failed`, res.status);
} catch (err) {
  if (err instanceof NetworkError && err.status === 401) {
    redirectToLogin();
  } else {
    throw err;
  }
}

การทำงานสุดท้ายในการทำงานแบบอะซิงก์/รอผล

บล็อก finally จะทำงานไม่ว่าบล็อก try จะสำเร็จหรือล้มเหลว เช่นเดียวกับ .finally() ของพรอมิส ใช้บล็อกนี้เพื่อคืนทรัพยากรหรือซ่อนสถานะการโหลด

async function loadData() {
  setLoading(true);
  try {
    const data = await fetch('/api/data').then(r => r.json());
    setData(data);
  } catch (err) {
    setError(err.message);
  } finally {
    setLoading(false); // always runs
  }
}

IIFE แบบอะซิงก์สำหรับจุดเริ่มต้นของโมดูล

ห่อจุดเริ่มต้นของสคริปต์ไว้ใน IIFE แบบอะซิงก์ เมื่อไม่สามารถใช้การรอระดับบนสุดได้

(async () => {
  const data = await fetchInitialData();
  renderApp(data);
})();

AbortController สำหรับการยกเลิก

ส่งสัญญาณของ AbortController ไปยังการดึงข้อมูลเพื่อยกเลิกคำขอที่กำลังดำเนินการอยู่ การดักจับ AbortError แยกต่างหากช่วยป้องกันไม่ให้แสดงข้อผิดพลาดแก่ผู้ใช้

const controller = new AbortController();

try {
  const data = await fetch(url, { signal: controller.signal }).then(r => r.json());
  setData(data);
} catch (err) {
  if (err.name !== 'AbortError') setError(err.message);
}

// Cancel:
controller.abort();

ตรวจสอบความเข้าใจ

โครงสร้างใดจัดการข้อผิดพลาดจากพรอมิสที่กำลังรอได้อย่างถูกต้อง

ทบทวน: การทำงานแบบอะซิงก์/รอผล

ฟังก์ชันแบบอะซิงก์จะคืนค่าพรอมิสเสมอ การรอจะหยุดการทำงานไว้จนกว่าพรอมิสจะเข้าสู่สถานะสิ้นสุด ใช้ try/catch สำหรับการจัดการข้อผิดพลาด สำหรับการดำเนินการแบบขนานให้ใช้ Promise.all() หลีกเลี่ยงการใช้ await ภายใน forEach โดยใช้การวนซ้ำทีละรายการหรือ Promise.all แทน AbortController ใช้ยกเลิกคำขอที่กำลังดำเนินการอยู่ การรอระดับบนสุดใช้ได้ในโมดูล ES

เริ่มต้นได้ฟรี

เรียนรู้ HTML ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
41
บทเรียน
163

คำถามที่พบบ่อย

บทเรียน “async/await และการจัดการข้อผิดพลาด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “async/await และการจัดการข้อผิดพลาด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “async/await และการจัดการข้อผิดพลาด”

เขียนฟังก์ชัน async ด้วยคีย์เวิร์ด await ครอบการเรียกที่มี await ไว้ในบล็อก try/catch และทำความเข้าใจว่า async/await เป็นรูปแบบไวยากรณ์ที่ช่วยให้ใช้งาน Promise ได้สะดวกขึ้น คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “async/await และการจัดการข้อผิดพลาด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม

ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Event Loop: Call Stack, Queue และ Microtasks
  2. Callback และ Callback Hell
  3. Promise: then, catch, finally และ Promise.all
  4. async/await และการจัดการข้อผิดพลาด
← กลับไปที่ Frontend Academy