ข้อผิดพลาด
พูดคุยเกี่ยวกับข้อผิดพลาด
ข้อผิดพลาดมีสองประเภท:
- ข้อผิดพลาดที่คาดไว้
- ข้อผิดพลาดที่ไม่คาดคิด
- ข้อผิดพลาดแบบ off-one
ข้อผิดพลาดที่คาดหวัง
ข้อผิดพลาดที่คาดหวังคือสถานะที่สิ่งผิดปกติเกิดขึ้น แต่คุณรู้ว่ามันอาจเกิดขึ้นดังนั้นคุณต้องจัดการกับมัน
เหล่านี้คือสิ่งที่ต้องการป้อนข้อมูลผู้ใช้หรือคำขอเซิร์ฟเวอร์ คุณรู้ว่าผู้ใช้อาจทำผิดพลาดหรือเซิร์ฟเวอร์อาจล่มดังนั้นคุณต้องเขียนรหัสตรวจสอบเพื่อให้แน่ใจว่าโปรแกรมขอให้ป้อนข้อมูลอีกครั้งหรือแสดงข้อความหรือพฤติกรรมอื่น ๆ ที่เหมาะสม
สิ่งเหล่านี้สามารถกู้คืนได้เมื่อจัดการ หากปล่อยทิ้งไว้จะกลายเป็นข้อผิดพลาดที่ไม่คาดคิด
ข้อผิดพลาดที่ไม่คาดคิด
ข้อผิดพลาดที่ไม่คาดคิด (บั๊ก) คือสถานะที่มีสิ่งผิดปกติเกิดขึ้นเนื่องจากรหัสผิด คุณรู้ว่าในที่สุดพวกเขาก็จะเกิดขึ้น แต่ไม่มีทางรู้ว่าจะจัดการกับพวกเขาที่ไหนหรืออย่างไรเพราะโดยนิยามแล้วพวกเขาไม่คาดคิด
นี่คือสิ่งต่าง ๆ เช่นข้อผิดพลาดทางไวยากรณ์และตรรกะ คุณอาจพิมพ์ผิดในรหัสของคุณคุณอาจเรียกใช้ฟังก์ชันที่มีพารามิเตอร์ที่ไม่ถูกต้อง โดยทั่วไปไม่สามารถกู้คืนได้
try..catch
มาพูดถึงtry..catch
กัน
ใน JavaScript throw
ไม่ได้ใช้กันทั่วไป หากคุณมองไปรอบ ๆ ตัวอย่างในโค้ดพวกมันจะอยู่ห่างกันไม่มากนักและมักจะมีโครงสร้างตามแนวของ
function example(param) {
if (!Array.isArray(param) {
throw new TypeError('"param" should be an array!');
}
...
}
ด้วยเหตุนี้try..catch
บล็อกจึงไม่ใช่สิ่งที่พบได้บ่อยสำหรับการควบคุมโฟลว์ โดยปกติแล้วการเพิ่มการตรวจสอบก่อนการเรียกใช้จะทำได้ง่ายมาก
สภาพแวดล้อมของ JavaScript ก็ค่อนข้างให้อภัยเช่นกันดังนั้นข้อผิดพลาดที่ไม่คาดคิดก็มักจะไม่ถูกตรวจสอบเช่นกัน
try..catch
ไม่จำเป็นต้องเป็นเรื่องผิดปกติ มีบางกรณีการใช้งานที่ดีซึ่งพบได้ทั่วไปในภาษาเช่น Java และ C # Java และ C # มีข้อดีของการcatch
สร้างแบบพิมพ์เพื่อให้คุณสามารถแยกความแตกต่างระหว่างข้อผิดพลาดที่คาดหวังและข้อผิดพลาดที่ไม่คาดคิด:
C # :
try
{
var example = DoSomething();
}
catch (ExpectedException e)
{
DoSomethingElse(e);
}
ตัวอย่างนี้อนุญาตให้มีข้อยกเว้นอื่น ๆ ที่ไม่คาดคิดไหลขึ้นและได้รับการจัดการที่อื่น (เช่นโดยการบันทึกและปิดโปรแกรม)
ใน JavaScript โครงสร้างนี้สามารถจำลองได้ผ่าน:
try {
let example = doSomething();
} catch (e) {
if (e instanceOf ExpectedError) {
DoSomethingElse(e);
} else {
throw e;
}
}
ไม่สง่างามซึ่งเป็นส่วนหนึ่งของเหตุผลว่าทำไมมันถึงผิดปกติ
ฟังก์ชั่น
พูดคุยเกี่ยวกับฟังก์ชั่น
หากคุณใช้หลักการความรับผิดชอบเดียวแต่ละชั้นเรียนและฟังก์ชั่นควรตอบสนองวัตถุประสงค์ที่เป็นเอกเทศ
ตัวอย่างเช่นauthenticate()
อาจรับรองความถูกต้องของผู้ใช้
สิ่งนี้อาจเขียนเป็น:
const user = authenticate();
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
หรืออาจเขียนเป็น:
try {
const user = authenticate();
// keep doing stuff
} catch (e) {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
}
ทั้งสองเป็นที่ยอมรับได้
สัญญา
พูดคุยเกี่ยวกับสัญญา
try..catch
สัญญามีรูปแบบที่ไม่ตรงกันของ โทรnew Promise
หรือPromise.resolve
เริ่มtry
รหัสของคุณ โทรthrow
หรือPromise.reject
ส่งcatch
รหัสไปให้คุณ
Promise.resolve(value) // try
.then(doSomething) // try
.then(doSomethingElse) // try
.catch(handleError) // catch
หากคุณมีฟังก์ชั่นแบบอะซิงโครนัสเพื่อตรวจสอบสิทธิ์ผู้ใช้คุณอาจเขียนเป็น:
authenticate()
.then((user) => {
if (user == null) {
// keep doing stuff
} else {
// handle expected error
}
});
หรืออาจเขียนเป็น:
authenticate()
.then((user) => {
// keep doing stuff
})
.catch((e) => {
if (e instanceOf AuthenticationError) {
// handle expected error
} else {
throw e;
}
});
ทั้งสองเป็นที่ยอมรับได้
การทำรัง
พูดคุยเกี่ยวกับการทำรัง
try..catch
สามารถซ้อนกันได้ authenticate()
วิธีการของคุณอาจมีtry..catch
บล็อกภายในเช่น:
try {
const credentials = requestCredentialsFromUser();
const user = getUserFromServer(credentials);
} catch (e) {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
}
คำสัญญาในทำนองเดียวกันสามารถซ้อนกันได้ authenticate()
วิธีการasync ของคุณอาจใช้สัญญา:
requestCredentialsFromUser()
.then(getUserFromServer)
.catch((e) => {
if (e instanceOf CredentialsError) {
// handle failure to request credentials
} else if (e instanceOf ServerError) {
// handle failure to get data from server
} else {
throw e; // no idea what happened
}
});
ดังนั้นคำตอบคืออะไร
ตกลงฉันคิดว่าถึงเวลาที่ฉันต้องตอบคำถามจริง:
ความล้มเหลวในการตรวจสอบถือว่าเป็นสิ่งที่คุณจะปฏิเสธสัญญาหรือไม่
คำตอบที่ง่ายที่สุดที่ฉันสามารถให้คือคุณควรปฏิเสธสัญญาทุกที่ที่คุณต้องการthrow
ยกเว้นถ้ามันเป็นรหัสซิงโครนัส
หากขั้นตอนการควบคุมของคุณง่ายขึ้นโดยมีการif
ตรวจสอบในthen
งบของคุณไม่จำเป็นต้องปฏิเสธสัญญา
หากโฟลว์การควบคุมของคุณง่ายขึ้นโดยการปฏิเสธสัญญาและจากนั้นตรวจสอบชนิดของข้อผิดพลาดในรหัสการจัดการข้อผิดพลาดให้ทำเช่นนั้น
reject
และไม่ได้กลับเท็จ แต่ถ้าคุณจะคาดหวังว่าคุ้มค่าที่จะเป็นBool
แล้วคุณก็ประสบความสำเร็จและคุณควรจะแก้ไขด้วย Bool โดยไม่คำนึงถึงความคุ้มค่า สัญญาที่มีการจัดเรียงของผู้รับมอบฉันทะค่า -reject
พวกเขาเก็บค่าที่ส่งกลับเท่านั้นดังนั้นถ้าค่าไม่สามารถได้คุณควรresolve
มิฉะนั้นคุณควร