ใช้ async/await ในเราต์ของคุณ และจัดการข้อผิดพลาดแบบอะซิงโครนัสโดยไม่ทำให้เซิร์ฟเวอร์ล่ม
เปิดบทเรียนนี้ใน Kodokonเราต์จริง ๆ ของคุณไม่ได้คืนอาร์เรย์ในหน่วยความจำ แต่จะอ่านไฟล์ คิวรีฐานข้อมูล และเรียก API อื่น ๆ การดำเนินการเหล่านี้ล้วนเป็นแบบอะซิงโครนัสทั้งสิ้น คุณรู้จัก async/await มาตั้งแต่คอร์ส JavaScript แล้ว มาดูวิธีใช้มันอย่างสะอาดในเซิร์ฟเวอร์กัน ข่าวดีอย่างแรกคือ ฟังก์ชันของเราต์สามารถเป็น async ได้
import express from "express";
import { readFile } from "node:fs/promises";
const app = express();
app.get("/report", async (req, res) => {
const raw = await readFile("report.json", "utf8");
res.json(JSON.parse(raw));
});
app.listen(3000);โค้ดนี้ทำงานได้... ตราบเท่าที่ report.json มีอยู่จริง หากการอ่านล้มเหลว โพรมิสจะถูกปฏิเสธ (rejected) และขึ้นอยู่กับเวอร์ชันของ Express คำขออาจค้างอยู่โดยไม่มีการตอบกลับ หรือข้อผิดพลาดอาจรั่วไหลไปในล็อก กฎของมืออาชีพคือ ทุกเราต์แบบอะซิงโครนัสต้องจัดการข้อผิดพลาดของตัวเอง ด้วย try/catch และ next(error)
app.get("/report", async (req, res, next) => {
try {
const raw = await readFile("report.json", "utf8");
res.json(JSON.parse(raw));
} catch (error) {
next(error);
}
});next(error) จะส่งข้อผิดพลาดต่อไปยัง ตัวจัดการข้อผิดพลาดส่วนกลาง (centralized error handler) ซึ่งเป็นมิดเดิลแวร์ที่มีสี่พารามิเตอร์ ประกาศไว้หลังเราต์ทั้งหมด จุดเดียวสำหรับบันทึกล็อกและจัดรูปแบบข้อผิดพลาด นี่คือสิ่งที่แยก API ที่ดูแลรักษาได้ ออกจากโปรเจกต์ทำเล่นสุดสัปดาห์
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({
error: "Internal server error"
});
});ปฏิกิริยาสุดท้ายที่ต้องฝึกให้ติดคือ การทำงานแบบขนาน (parallelism) การดำเนินการอิสระสองอย่างที่ต่อกันด้วย await สองตัวจะทำงานทีละอันตามลำดับ ส่วน Promise.all จะเริ่มทั้งสองพร้อมกัน เวลาตอบสนองจึงเท่ากับตัวที่ช้าที่สุด ไม่ใช่ผลรวมของทั้งสอง
async function fetchUsers() {
return [{ id: 1, name: "Ada" }];
}
async function fetchTasks() {
return [{ id: 1, title: "Review the code" }];
}
app.get("/dashboard", async (req, res, next) => {
try {
const [users, tasks] = await Promise.all([
fetchUsers(),
fetchTasks()
]);
res.json({ users, tasks });
} catch (error) {
next(error);
}
});async คุณจะทำอย่างไรกับข้อผิดพลาดที่ถูกดักจับด้วย catch?console.log แล้วทำงานต่อnext(error) เพื่อส่งต่อไปยังตัวจัดการข้อผิดพลาดawait สองตัวเรียงลำดับกันPromise.allsetTimeout คั่นระหว่างทั้งสองerr เป็นตัวแรกerrorHandler