มีบทบัญญัติให้เป็นลองจับกระชากจาวาสคริปต์ ในขณะที่เป็นจาวาหรือภาษาอื่น ๆ มันเป็นข้อบังคับที่จะต้องมีการจัดการข้อผิดพลาดฉันไม่เห็นใครใช้พวกเขาในจาวาสคริปต์ในระดับที่สูงขึ้น มันไม่ใช่วิธีปฏิบัติที่ดีหรือเพียงแค่เราไม่ต้องการใช้งานจาวาสคริปต์
มีบทบัญญัติให้เป็นลองจับกระชากจาวาสคริปต์ ในขณะที่เป็นจาวาหรือภาษาอื่น ๆ มันเป็นข้อบังคับที่จะต้องมีการจัดการข้อผิดพลาดฉันไม่เห็นใครใช้พวกเขาในจาวาสคริปต์ในระดับที่สูงขึ้น มันไม่ใช่วิธีปฏิบัติที่ดีหรือเพียงแค่เราไม่ต้องการใช้งานจาวาสคริปต์
คำตอบ:
หนึ่งควรหลีกเลี่ยงthrow
ข้อผิดพลาดเป็นวิธีการผ่านเงื่อนไขข้อผิดพลาดในการใช้งาน
throw
คำสั่งควรใช้เฉพาะ "สำหรับเรื่องนี้ไม่ควรเกิดขึ้นความผิดพลาดและการเผาไหม้. อย่ากู้คืนอย่างหรูหราในทางใดทางหนึ่ง"
try catch
อย่างไรก็ตามถูกใช้ในสถานการณ์ที่วัตถุโฮสต์หรือ ECMAScript อาจทำให้เกิดข้อผิดพลาด
ตัวอย่าง:
var json
try {
json = JSON.parse(input)
} catch (e) {
// invalid json input, set to null
json = null
}
คำแนะนำในชุมชนnode.jsคือคุณผ่านข้อผิดพลาดในการเรียกกลับ (เนื่องจากข้อผิดพลาดเกิดขึ้นสำหรับการดำเนินการแบบอะซิงโครนัสเท่านั้น) เป็นอาร์กิวเมนต์แรก
fs.readFile(uri, function (err, fileData) {
if (err) {
// handle
// A. give the error to someone else
return callback(err)
// B. recover logic
return recoverElegantly(err)
// C. Crash and burn
throw err
}
// success case, handle nicely
})
นอกจากนี้ยังมีปัญหาอื่น ๆ เช่นลอง / จับมีราคาแพงมากและมันก็น่าเกลียดและมันก็ไม่ได้ทำงานกับการทำงานแบบอะซิงโครนัส
ดังนั้นเนื่องจากการดำเนินการแบบซิงโครนัสไม่ควรเกิดข้อผิดพลาดและไม่สามารถทำงานกับการดำเนินการแบบอะซิงโครนัสจึงไม่มีใครลองใช้ catch catch ยกเว้นข้อผิดพลาดที่เกิดจากวัตถุโฮสต์หรือ ECMAScript
Error
แต่พวกมันอยู่ห่างกันไม่มากนัก
document.getElementById
null
เช่นเดียวกันสามารถทำได้เกือบทุกกรณี
ลอง / จับใน Javascript ไม่ได้เป็นสัญลักษณ์แสดงหัวข้อย่อยเหมือนในภาษาอื่นเนื่องจากลักษณะอะซิงโครนัสของ Javascript ลองพิจารณาตัวอย่างนี้:
try {
setTimeout(function() {
do_something_that_throws();
}, 1000);
}
catch (e) {
alert("You won't see this!");
}
ปัญหาคือว่าการควบคุมการไหลออกจากtry
บล็อกก่อนที่จะdo_something_that_throws()
ได้รับการดำเนินการดังนั้นข้อผิดพลาดที่เกิดขึ้นในการโทรกลับไม่เคยได้รับการจับ
ดังนั้นลอง / จับนั้นโดยทั่วไปจะไม่เหมาะสมในหลาย ๆ กรณีและไม่ชัดเจนเสมอไปว่ามีบางสิ่งที่เรียกใช้โค้ดแบบอะซิงโครนัสหรือไม่ โชคดีที่จาวาสคริปต์ที่มีรูปแบบเฉพาะเธรดเดียวแบบอะซิงโครนัสโทรกลับและการสนับสนุนสำหรับการปิดที่เกิดขึ้นจริงให้ทางเลือกที่สง่างาม: การจัดการข้อผิดพลาดสไตล์ต่อเนื่อง เพียงผ่านการตอบสนองที่เหมาะสมกับข้อผิดพลาดใด ๆ เช่นฟังก์ชั่นเช่น:
setTimeout(function () {
do_something_that_calls_err(function(err) {
alert("Something went wrong, namely this: " + err);
}),
1000);
จำนวนมากของคำตอบเหล่านี้เป็นบิตเก่าและไม่คำนึงถึงคุณสมบัติ ES7 ใหม่และasync
await
การใช้async
/ await
คุณสามารถรับโฟลว์การควบคุมแบบอะซิงโครนัสได้ตามที่คุณต้องการ:
async function email(address) {
try {
// Do something asynchronous that may throw...
await sendEmail({ to: address, from: 'noreply@domain.com`, subject: 'Hello' })
} catch(err) {
if (err instanceof SomeCustomError) {
elegantlyHandleError(err)
} else {
throw err
}
}
})
เรียนรู้เพิ่มเติมเกี่ยวกับasync
/await
ที่นี่ คุณสามารถใช้async
/ await
ตอนนี้ใช้Babel
try-catch ใน javascript นั้นถูกต้องและมีประโยชน์เช่นเดียวกับในภาษาอื่นที่ใช้งานได้ มีเหตุผลสำคัญอย่างหนึ่งที่ไม่ได้ใช้ใน javascript มากเท่าภาษาอื่น มันเป็นเหตุผลเดียวกันกับจาวาสคริปต์ที่ถูกมองว่าเป็นภาษาสคริปต์ที่น่าเกลียด แต่ก็เป็นเหตุผลเดียวกับที่คนทั่วไปคิดว่าโปรแกรมเมอร์จาวาสคริปต์ไม่ใช่โปรแกรมเมอร์ตัวจริง:
ข้อเท็จจริงที่ว่ามีผู้คนมากมายที่สัมผัสกับจาวาสคริปต์ (โดยอาศัยเพียงภาษาที่รองรับโดยเบราว์เซอร์) หมายความว่าคุณมีรหัสไม่เป็นมืออาชีพมากมาย แน่นอนว่ายังมีเหตุผลเล็กน้อยอีกหลายประการ:
catch
สามารถทำได้ (แบบอะซิงโครนัส)ไม่ควรใช้try-catch แต่คุณควรเรียนรู้วิธีใช้อย่างถูกต้อง - เหมือนทุกอย่างในการเขียนโปรแกรม
ฉันเชื่อว่าเหตุผลส่วนใหญ่ที่try..catch
หาได้ยากใน JavaScript คือเนื่องจากภาษามีความอดทนสูงสำหรับข้อผิดพลาด สถานการณ์ส่วนใหญ่สามารถจัดการได้โดยใช้การตรวจสอบโค้ดค่าเริ่มต้นที่ดีและเหตุการณ์แบบอะซิงโครนัส ในบางกรณีเพียงใช้รูปแบบจะป้องกันปัญหา:
function Foo() {
//this may or may not be called as a constructor!!
//could accidentally overwrite properties on window
}
function Bar() {
if (!(this instanceof Bar)) {
return new Bar();
}
//this will only work on Bar objects, and wont impact window
}
ปัญหาสำคัญบางอย่างในภาษาอื่น ๆ ที่ทำให้เกิดข้อยกเว้นเกิดขึ้นก็ไม่มีอยู่ใน JS การหล่อแบบไม่จำเป็นต้องใช้เวลาส่วนใหญ่ โดยปกติแล้ววิธีที่ต้องการจะใช้ในการตรวจสอบคุณสมบัติ (บังคับใช้อินเทอร์เฟซเฉพาะ) แทน:
function doFoo(arg) {
if (arg.foo) {
arg.foo();
} else {
Bar.prototype.foo.call(arg);
}
}
ด้วยการเพิ่มasync
/ await
เพื่อภาษาtry..catch
กำลังเป็นที่แพร่หลายมากขึ้น สัญญาว่าจะเป็นรูปแบบอะซิงโครนัสของtry..catch
มันทำให้รู้สึกว่าควรคาดหวัง:
doSomething().then(
doSomethingWithResult,
doSomethingWithError
)
เป็นแทนที่จะเขียนเป็น:
try {
const result = await doSomething()
doSomethingWithResult(result)
} catch (e) {
doSomethingWithError(e)
}
อาจเป็นเพราะเหตุผลอื่น ๆ ที่ลอง / จับไม่ได้ใช้อย่างมากใน Javascript คือโครงสร้างไม่พร้อมใช้งานใน Javascript เวอร์ชันแรก ... ซึ่งถูกเพิ่มเข้ามาในภายหลัง
ดังนั้นเบราว์เซอร์รุ่นเก่าบางรุ่นจึงไม่รองรับ (อันที่จริงแล้วมันอาจทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์ / ไวยากรณ์ในเบราว์เซอร์รุ่นเก่าบางสิ่งที่ยากต่อการ "ตั้งโปรแกรมป้องกัน" มากกว่าข้อผิดพลาดประเภทอื่น ๆ ส่วนใหญ่)
ที่สำคัญกว่านั้นเนื่องจากไม่สามารถใช้งานได้ในตอนแรกฟังก์ชัน Javascript ในตัวที่เปิดตัวครั้งแรก (สิ่งที่เรียกว่า "ห้องสมุด" ฟังก์ชั่นในหลายภาษา) ไม่ได้ใช้ประโยชน์ (มันทำงานได้ไม่ดีนักในการ "จับ" ข้อผิดพลาดจาก someobject.somefunction () ถ้ามันไม่ "โยน" แต่ให้ส่งคืน "null" แทนเมื่อพบปัญหา)
อีกเหตุผลที่เป็นไปได้ก็คือกลไกลอง / จับไม่ได้ดูเหมือนว่าจำเป็นในตอนแรก (และดูเหมือนจะไม่เป็นประโยชน์ทั้งหมด) มันจำเป็นจริงๆเท่านั้นเมื่อมีการโทรซ้อนกันหลายระดับเป็นประจำ การส่งคืน ERRNO บางประเภทอาจใช้งานได้ดีสำหรับการโทรโดยตรง (แม้ว่าจะทำให้มีประโยชน์จริง ๆ ทุกครั้งที่มีให้บริการแนวทางปฏิบัติที่ดีที่สุดในภาษาส่วนใหญ่คือการใช้ทุกที่แทนที่จะใช้กับการโทรที่ซ้อนกันอย่างล้ำลึก) เนื่องจากเดิมคาดว่าจาวาสคริปต์ลอจิกจะเล็กและเรียบง่าย (หลังจากทั้งหมดมันเป็นเพียงส่วนเสริมของเว็บเพจ :-), การเรียกใช้ฟังก์ชันไม่คาดว่าจะซ้อนกันอย่างลึกล้ำและกลไกการลอง / จับไม่จำเป็น
ฉันเชื่อว่าพวกเขาไม่ได้ใช้สิ่งเหล่านี้มากนักเนื่องจากการโยนข้อยกเว้นในโค้ดด้านไคลเอนต์ Javascript ทำให้การดีบักหน้าเว็บทำได้ยากขึ้น
แทนที่จะโยนข้อยกเว้นโดยทั่วไปฉันต้องการแสดงกล่องแจ้งเตือน (เช่นalert("Error, invalid...");
)
อาจฟังดูแปลก แต่ข้อผิดพลาดของ Javascript เกิดขึ้นที่ฝั่งไคลเอ็นต์หากลูกค้าใช้หน้าเว็บที่คุณสร้างขึ้นและหน้านั้นมีข้อยกเว้นเว้นแต่ลูกค้าเป็นผู้ใช้เทคโนโลยีที่เข้าใจง่ายไม่มีทางที่เขาจะสามารถบอกได้ คุณว่าปัญหาคืออะไร
เขาจะโทรหาคุณโดยบอกว่า: "เฮ้, หน้า X ใช้งานไม่ได้!"แล้วมันก็ขึ้นอยู่กับคุณแล้วว่าจะพบสิ่งที่ผิดพลาดและในรหัส
โดยการใช้กล่องการแจ้งเตือนแทนที่จะเป็นไปได้มากขึ้นที่เขาจะโทรหาและพูดว่า: "เฮ้เมื่อฉันคลิกที่ปุ่ม A ของหน้า X มันจะแสดงกล่องที่บอกว่า ... "เชื่อฉันสิมันจะง่ายกว่ามากในการค้นหา ข้อผิดพลาด
While in java or *any other language* it is mandatory to have error handling...
- ไม่จริง Java ใช่ แต่มีภาษามากมายที่ไม่ยืนยันในการลองจับ (เช่น C #)