Promise: then, catch, finally และ Promise.all
สร้างและเชื่อมต่อ Promise จัดการข้อผิดพลาดในบล็อก catch ทำความสะอาดใน finally และทำให้ Promise หลายรายการทำงานแบบขนานด้วย Promise.all
Promise: then, catch, finally และ Promise.all เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
พรอมิสคืออะไร
พรอมิสแสดงแทนค่าที่จะพร้อมใช้งานในอนาคต โดยเป็นออบเจ็กต์ที่มีหนึ่งในสามสถานะ ได้แก่ รอดำเนินการ (สถานะเริ่มต้น) สำเร็จแล้ว (ได้ผลลัพธ์เป็นค่า) หรือ ถูกปฏิเสธ (ล้มเหลวพร้อมเหตุผล) เมื่อพรอมิสเข้าสู่สถานะสิ้นสุดแล้ว สถานะนั้นจะเปลี่ยนแปลงไม่ได้
การสร้างพรอมิส
สร้างพรอมิสด้วยตัวสร้าง new Promise(executor) ฟังก์ชันตัวดำเนินการจะได้รับฟังก์ชันเรียกกลับ resolve และ reject ให้เรียก resolve พร้อมค่าที่แสดงถึงความสำเร็จ หรือเรียก reject พร้อมข้อผิดพลาด
const delay = (ms) => new Promise((resolve) => {
setTimeout(resolve, ms);
});
const fetchData = (url) => new Promise((resolve, reject) => {
fetch(url)
.then(res => res.json())
.then(resolve)
.catch(reject);
});การจัดการผลสำเร็จของพรอมิส
promise.then(onFulfilled) จะลงทะเบียนฟังก์ชันเรียกกลับให้ทำงานเมื่อพรอมิสสำเร็จ ฟังก์ชันเรียกกลับจะได้รับค่าที่แก้ไขแล้ว .then() จะคืนค่าพรอมิสใหม่ จึงสามารถเชื่อมต่อการทำงานเป็นลำดับได้
fetch('/api/users')
.then(response => response.json())
.then(users => {
console.log('Users:', users);
return users.length;
})
.then(count => console.log('Count:', count));การจัดการข้อผิดพลาดของพรอมิส
promise.catch(onRejected) ใช้จัดการการปฏิเสธ หากวางไว้ท้ายลำดับการเชื่อมต่อ จะตรวจจับข้อผิดพลาดจากขั้นตอนใด ๆ ที่อยู่ก่อนหน้าได้
fetch('/api/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(data => processData(data))
.catch(err => {
console.error('Failed:', err.message);
showErrorToUser();
});การทำงานสุดท้าย — ทำงานเสมอ
promise.finally(onFinally) จะทำงานไม่ว่าพรอมิสจะสำเร็จหรือถูกปฏิเสธ เหมาะอย่างยิ่งสำหรับการล้างทรัพยากร เช่น ซ่อนตัวแสดงการโหลด ปลดล็อก หรือบันทึกข้อมูลการใช้งาน
showSpinner();
fetch('/api/data')
.then(res => res.json())
.then(render)
.catch(handleError)
.finally(() => hideSpinner()); // always runsการเชื่อมต่อพรอมิส — การคืนค่า
คืนค่าจาก .then() แล้วค่านั้นจะกลายเป็นค่าที่แก้ไขแล้วของ .then() ถัดไป หากคืนค่าพรอมิสใหม่ ก็จะสามารถเชื่อมต่อการดำเนินการแบบอะซิงก์ให้ทำงานตามลำดับได้
getUser(id)
.then(user => getOrders(user.id)) // return Promise
.then(orders => orders[0]) // return value
.then(order => console.log(order)); // receive orderPromise.all() — ทำงานแบบขนาน
Promise.all([p1, p2, p3]) จะรอให้พรอมิสทั้งหมดสำเร็จ แล้วคืนค่าอาร์เรย์ของผลลัพธ์ตามลำดับเดิม หากพรอมิสใดพรอมิสหนึ่งถูกปฏิเสธ การดำเนินการทั้งหมดจะถูกปฏิเสธทันที
const [user, posts, comments] = await Promise.all([
fetch('/api/user/1').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json()),
]);
// All three run in parallel — much faster than sequentialPromise.allSettled() — ไม่ล้มเหลวทันที
Promise.allSettled() จะรอให้พรอมิสทั้งหมดเข้าสู่สถานะสิ้นสุด (สำเร็จหรือถูกปฏิเสธ) แล้วคืนค่าอาร์เรย์ของออบเจ็กต์ผลลัพธ์ที่มีสถานะกับค่า หรือสถานะกับเหตุผล เหมาะเมื่อไม่ต้องการให้ความล้มเหลวเพียงรายการเดียวทำให้ผลลัพธ์ทั้งหมดสูญเสียไป
const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(result => {
if (result.status === 'fulfilled') use(result.value);
else logError(result.reason);
});Promise.race() และ Promise.any()
Promise.race() จะให้ผลสำเร็จหรือถูกปฏิเสธตามพรอมิสแรกที่เข้าสู่สถานะสิ้นสุด ส่วน Promise.any() จะให้ผลสำเร็จตามพรอมิสแรกที่สำเร็จ โดยไม่สนใจการปฏิเสธ และจะถูกปฏิเสธก็ต่อเมื่อทุกพรอมิสถูกปฏิเสธ เหมาะสำหรับการจำกัดเวลาและการทำงานสำรอง
// Timeout pattern:
const withTimeout = (promise, ms) => Promise.race([
promise,
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms))
]);การสร้างพรอมิสที่อยู่ในสถานะสิ้นสุดแล้ว
Promise.resolve(value) สร้างพรอมิสที่สำเร็จแล้วพร้อมค่า value ส่วน Promise.reject(error) สร้างพรอมิสที่ถูกปฏิเสธแล้ว มีประโยชน์สำหรับการทดสอบและฟังก์ชันปรับให้เข้ากัน
const p = Promise.resolve(42);
p.then(v => console.log(v)); // 42เหตุการณ์การปฏิเสธที่ไม่ได้จัดการ
หากพรอมิสถูกปฏิเสธโดยไม่มี .catch() จะกลายเป็นการปฏิเสธที่ไม่ได้จัดการ เบราว์เซอร์สมัยใหม่และ Node.js จะแสดงคำเตือน ควรผูกตัวจัดการการปฏิเสธไว้เสมอ หรือใช้ try/catch ร่วมกับการทำงานแบบอะซิงก์/รอผล
window.addEventListener('unhandledrejection', event => {
console.error('Unhandled rejection:', event.reason);
event.preventDefault();
});ตรวจสอบความเข้าใจ
เมธอดแบบสแตติกใดทำให้พรอมิสหลายรายการทำงานแบบขนาน และให้ผลสำเร็จเป็นอาร์เรย์ที่มีผลลัพธ์ทั้งหมด
ทบทวน: พรอมิส
ใช้ .then() สำหรับผลสำเร็จ ใช้ .catch() สำหรับข้อผิดพลาด และใช้ .finally() สำหรับการล้างทรัพยากร การเชื่อมต่อจะส่งค่าต่อกันไป Promise.all() ทำงานแบบขนาน Promise.allSettled() ยอมรับความล้มเหลวบางส่วน Promise.race() ใช้สำหรับผลลัพธ์ที่เร็วที่สุด ควรจัดการการปฏิเสธเสมอ โค้ดสมัยใหม่ใช้การทำงานแบบอะซิงก์/รอผล ซึ่งเป็นรูปแบบไวยากรณ์ย่อของพรอมิส
เรียนรู้ HTML ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 41
- บทเรียน
- 163
คำถามที่พบบ่อย
บทเรียน “Promise: then, catch, finally และ Promise.all” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Promise: then, catch, finally และ Promise.all” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Promise: then, catch, finally และ Promise.all”
สร้างและเชื่อมต่อ Promise จัดการข้อผิดพลาดในบล็อก catch ทำความสะอาดใน finally และทำให้ Promise หลายรายการทำงานแบบขนานด้วย Promise.all คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “Promise: then, catch, finally และ Promise.all” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม
ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Event Loop: Call Stack, Queue และ Microtasks
- Callback และ Callback Hell
- Promise: then, catch, finally และ Promise.all
- async/await และการจัดการข้อผิดพลาด