คำสั่งส่งคืนภายในบล็อก try / catch ทำงานอย่างไร
function example() {
try {
return true;
}
finally {
return false;
}
}
ฉันคาดหวังว่าผลลัพธ์ของฟังก์ชันนี้จะเป็นtrue
แต่มันกลับเป็นfalse
!
คำสั่งส่งคืนภายในบล็อก try / catch ทำงานอย่างไร
function example() {
try {
return true;
}
finally {
return false;
}
}
ฉันคาดหวังว่าผลลัพธ์ของฟังก์ชันนี้จะเป็นtrue
แต่มันกลับเป็นfalse
!
คำตอบ:
สุดท้ายมักจะดำเนินการ นั่นคือสิ่งที่มีไว้สำหรับซึ่งหมายความว่าผลตอบแทนจะถูกใช้ในกรณีของคุณ
คุณจะต้องเปลี่ยนรหัสของคุณเพื่อให้เป็นแบบนี้:
function example() {
var returnState = false; // initialisation value is really up to the design
try {
returnState = true;
}
catch {
returnState = false;
}
finally {
return returnState;
}
}
โดยทั่วไปคุณไม่ต้องการมีคำสั่ง return มากกว่าหนึ่งคำสั่งในฟังก์ชันสิ่งนี้จึงเป็นสาเหตุ
อ้างอิงจาก ECMA-262 (5ed ธันวาคม 2009) ในหน้า 96:
การผลิต
TryStatement : try Block Finally
ได้รับการประเมินดังนี้:
- ให้ B เป็นผลลัพธ์ของการประเมิน Block
- ให้ F เป็นผลลัพธ์ของการประเมินในที่สุด
- ถ้าประเภท F. เป็นปกติให้ส่งคืน B
- กลับ F.
และจากหน้า 36:
ประเภทแล้วเสร็จจะใช้ในการอธิบายพฤติกรรมของงบ (
break
,continue
,return
และthrow
) ที่ดำเนินการถ่ายโอนต่างแดนของการควบคุม ค่าของชนิดเสร็จเป็นอเนกประสงค์ของรูปแบบ(ชนิดค่าเป้าหมาย)ที่ประเภทเป็นหนึ่งnormal
,break
,continue
,return
หรือthrow
, ค่าใดค่าภาษา ECMAScript หรือเปล่าและเป้าหมายใด ๆ ที่ระบุ ECMAScript หรือเปล่า
เป็นที่ชัดเจนว่าreturn false
จะกำหนดชนิดของความสำเร็จของในที่สุดก็เป็นผลตอบแทนที่ทำให้เกิดtry ... finally
จะทำอย่างไร4. กลับ F
เมื่อคุณใช้finally
รหัสใด ๆ ในบล็อกนั้นจะเริ่มทำงานก่อนที่เมธอดจะออก เนื่องจากคุณกำลังใช้ผลตอบแทนในfinally
บล็อกจึงเรียกreturn false
และลบล้างค่าก่อนหน้าreturn true
ในtry
บล็อก
(คำศัพท์อาจไม่ถูกต้องนัก)
การเขียนบล็อกใหม่ในที่สุดลองบล็อกการส่งคืน (พูดเปรียบเปรย)
แค่อยากจะชี้ให้เห็นว่าถ้าคุณส่งคืนบางสิ่งจากในที่สุดมันจะถูกส่งคืนจากฟังก์ชัน แต่ถ้าในที่สุดไม่มีคำว่า 'return' มันจะถูกส่งกลับค่าจาก try block;
function example() {
try {
return true;
}
finally {
console.log('finally')
}
}
console.log(example());
// -> finally
// -> true
ดังนั้น -finally- return
ปรับเปลี่ยนการกลับมาของ return
-try-
ทำไมคุณถึงได้รับเท็จคุณกลับมาในที่สุด สุดท้ายบล็อกควรรันเสมอ ดังนั้นreturn true
การเปลี่ยนแปลงของคุณเป็นreturn false
function example() {
try {
return true;
}
catch {
return false;
}
}
เท่าที่ฉันรู้finally
บล็อกจะดำเนินการเสมอไม่ว่าคุณจะมีreturn
คำสั่งภายในtry
หรือไม่ก็ตาม Ergo คุณจะได้รับค่าที่ส่งคืนโดยreturn
คำสั่งภายในบล็อกในที่สุด
ฉันทดสอบกับ Firefox 3.6.10 และ Chrome 6.0.472.63 ทั้งใน Ubuntu เป็นไปได้ว่าโค้ดนี้อาจทำงานแตกต่างจากเบราว์เซอร์อื่น
กลับมาจากบล็อกสุดท้าย
ถ้า
finally
-block ส่งคืนค่าค่านี้จะกลายเป็นค่าส่งคืนของtry-catch-finally
คำสั่งทั้งหมดโดยไม่คำนึงถึงreturn
คำสั่งใด ๆ ในtry
และcatch
-blocks
ข้อมูลอ้างอิง: developer.mozilla.org
ฉันจะให้คำตอบที่แตกต่างออกไปเล็กน้อยที่นี่: ใช่ทั้ง the try
และfinally
block ถูกเรียกfinally
ใช้งานและมีความสำคัญเหนือกว่าค่า "return" ที่แท้จริงสำหรับฟังก์ชัน อย่างไรก็ตามค่าส่งคืนเหล่านี้ไม่ได้ใช้ในโค้ดของคุณเสมอไป
นี่คือเหตุผล:
res.send()
จาก Express.js ซึ่งสร้างการตอบสนอง HTTP และส่งไปtry
และfinally
บล็อกทั้งสองจะเรียกใช้ฟังก์ชันนี้ดังนี้:try {
// Get DB records etc.
return res.send('try');
} catch(e) {
// log errors
} finally {
return res.send('finally');
}
รหัสนี้จะแสดงสตริงtry
ในเบราว์เซอร์ของคุณ นอกจากนี้ตัวอย่างจะแสดงข้อผิดพลาดในคอนโซลของคุณ res.send()
ฟังก์ชั่นที่เรียกว่าเป็นครั้งที่สอง สิ่งนี้จะเกิดขึ้นกับอะไรก็ได้ที่เป็นฟังก์ชัน บล็อก try-catch-ในที่สุดจะทำให้ความจริงนี้สับสนกับสายตาที่ไม่ได้รับการฝึกฝนเพราะ (โดยส่วนตัว) ฉันเชื่อมโยงreturn
ค่ากับขอบเขตของฟังก์ชันเท่านั้น
imho ทางออกที่ดีที่สุดของคุณคือการไม่เคยใช้return
ภายในfinally
บล็อก จะทำให้โค้ดของคุณซับซ้อนเกินไปและอาจปกปิดข้อผิดพลาด
ในความเป็นจริงมีการตั้งค่ากฎการตรวจสอบโค้ดเริ่มต้นใน PHPStorm ที่ให้ "คำเตือน" สำหรับสิ่งนี้:
https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
finally
ทำอะไร?ฉันจะใช้finally
เพื่อล้างสิ่งต่างๆเท่านั้น สิ่งใดก็ตามที่ไม่สำคัญสำหรับค่าที่ส่งคืนของฟังก์ชัน
มันอาจจะทำให้รู้สึกว่าคุณคิดเกี่ยวกับเรื่องนี้เพราะเมื่อคุณขึ้นอยู่กับบรรทัดของรหัสภายใต้finally
คุณจะสมมติว่าอาจจะมีข้อผิดพลาดในหรือtry
catch
แต่ 2 รายการสุดท้ายเป็นส่วนประกอบสำคัญของการจัดการข้อผิดพลาด เพียงแค่ใช้return
ในtry
และcatch
แทน
สุดท้ายควรจะรันทุกครั้งที่ส่วนท้ายของ try catch block ดังนั้น (ตามข้อกำหนด) จึงเป็นสาเหตุที่คุณได้รับการส่งคืนเท็จ โปรดทราบว่าเป็นไปได้ทั้งหมดที่เบราว์เซอร์ที่แตกต่างกันจะมีการใช้งานที่แตกต่างกัน
อะไรประมาณนี้
doubleReturn();
function doubleReturn() {
let sex = 'boy';
try {
return sex;
console.log('this never gets called...');
} catch (e) {} finally {
sex = 'girl';
alert(sex);
}
}