`अंत में` वापसी की कोशिश करता है `कोशिश` क्यों?


94

कोशिश / कैच ब्लॉक काम के अंदर रिटर्न स्टेटमेंट कैसे होता है?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

मैं इस फ़ंक्शन के आउटपुट की उम्मीद कर रहा हूं true, लेकिन इसके बजाय यह है false!


दूसरों के लिए, कैच ब्लॉक में रिटर्न झूठा करें, अंत में नहीं।
हबीबासनी

जवाबों:


91

अंत में हमेशा निष्पादित। यही वह है, जिसका अर्थ है कि यह वापसी है जो आपके मामले में उपयोग की जाती है।

आप अपना कोड बदलना चाहते हैं, इसलिए यह इस प्रकार है:

function example() { 
    var returnState = false; // initialisation value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

सामान्यतया आप किसी फ़ंक्शन में एक से अधिक रिटर्न स्टेटमेंट नहीं चाहते हैं, इस तरह की चीजें हैं।


45
मेरा तर्क होगा कि एक से अधिक रिटर्न स्टेटमेंट हमेशा खराब नहीं होते हैं - अधिक चर्चा के लिए stackoverflow.com/questions/36707/… देखें ।
कास्त्रोहेंगे

5
मैं भी एक वापसी नियम के बारे में असहमत हूं। आपको अंत में कभी नहीं लौटना चाहिए, हालांकि (सी # में, इसकी अनुमति भी नहीं है)।
एरिक्कलेन

@erikkallen - यह एक अच्छी बात है। TCF ब्लॉक के बाहर एक रिटर्न सबसे अच्छा होगा लेकिन उदाहरण कोड थोड़ा मजबूर होगा :)
annakata

1
@ कस्ट्रोहेंज - यह एक कठिन और तेज़ नियम नहीं है, लेकिन उस धागे में अधिकांश कॉप्टर-उदाहरण बहुत ही विवादित हैं, और मुझे जो एकमात्र वैध मामला दिखाई दे रहा है, वह है "गार्ड क्लॉज़" (मूल रूप से इनपुट डेटा की जाँच करने का पैटर्न) समारोह और सशर्त लौटने)। यह पूरी तरह से वैध मामला है, लेकिन वास्तव में उन रिटर्न अपवाद होने चाहिए (फिर से कठिन और तेज नहीं)।
अन्नकूट

1
वास्तव में IE6 और IE7 में, हमेशा एक बहुत ही गंभीर ब्राउज़र बग के कारण सभी मामलों में निष्पादित नहीं होता है। विशेष रूप से - यदि एक अपवाद अंततः कोशिश में ब्लॉक में फेंक दिया जाता है जो उच्च स्तर की कोशिश-पकड़ से घिरा नहीं है, तो अंत में ब्लॉक निष्पादित नहीं करेगा। यहाँ एक परीक्षण मामला है jsfiddle.net/niallsmart/aFjKq । यह समस्या IE8 में ठीक किया गया था।
नियाल स्मार्ट

43

ECMA-262 (5ed, दिसंबर 2009) के अनुसार, पीपी 96 में:

उत्पादन TryStatement : try Block Finallyका मूल्यांकन निम्नानुसार किया जाता है:

  1. बता दें कि B, ब्लॉक के मूल्यांकन का परिणाम है।
  2. चलो अंत में मूल्यांकन करने का परिणाम एफ है।
  3. यदि F.type सामान्य है, तो B वापस करें।
  4. वापसी एफ।

और पीपी से 36:

समापन प्रकार बयान के व्यवहार (व्याख्या करने के लिए प्रयोग किया जाता है break, continue, returnऔर throw) है कि नियंत्रण से nonlocal स्थानान्तरण प्रदर्शन करते हैं। समापन प्रकार के मान फार्म की ट्रिपल कर रहे हैं (प्रकार, मूल्य, लक्ष्य) है, जहां प्रकार में से एक है normal, break, continue, return, या throw, मूल्य किसी भी ECMAScript भाषा मूल्य या खाली है, और लक्ष्य किसी भी ECMAScript पहचानकर्ता या खाली है।

यह स्पष्ट है कि अंत में वापसी के रूप में return falseपूरा होने का प्रकार सेट होगा , जो करने का कारण बनता है 4. रिटर्न एफtry ... finally


2
इस प्रश्न के सभी प्रकार के "मूल रूप से सही लेकिन किसी तरह से स्क्विशी और गैर-स्पष्ट" उत्तर को पढ़ने के बाद, यह वास्तव में इसका मतलब बना। कुंजी बिट यह था कि जो कुछ भी होता है वह ट्राइ + के अंत में (रिटर्न या थ्रो या सिर्फ सामान्य प्रवाह) याद किया जाता है जबकि यह अंत में भागता है और फिर वास्तव में तभी होता है जब अंत में कुछ भी नहीं होता है।
रोकें

14

जब आप उपयोग करते हैं finally, तो उस ब्लॉक के भीतर कोई भी कोड विधि से बाहर निकलने से पहले आग लग जाती है। क्योंकि आप में एक वापसी का उपयोग कर रहे finallyब्लॉक, यह कहता है return falseऔर पिछले ओवरराइड करता है return trueमें tryब्लॉक।

(शब्दावली बहुत सही नहीं हो सकती है।)


3

आप झूठे क्यों हो रहे हैं क्या आप अंततः ब्लॉक में वापस आ गए हैं। अंत में ब्लॉक को हमेशा निष्पादित करना चाहिए। इसलिए आपके return trueपरिवर्तनreturn false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}

3

अंत में ब्लॉक रीराइट्स ब्लॉक रिटर्न (आलंकारिक रूप से बोलने) की कोशिश करते हैं।

बस यह इंगित करना चाहता था, कि यदि आप अंततः से कुछ वापस करते हैं, तो यह फ़ंक्शन से वापस आ जाएगा। लेकिन अगर अंत में कोई 'रिटर्न' शब्द नहीं है - यह कोशिश ब्लॉक से मान लौटाया जाएगा;

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

सो-फ़िनिश- रिटर्न्स ऑफ़ returnद रिटर्न -try- return


1

जहां तक ​​मुझे पता है, finallyब्लॉक हमेशा निष्पादित करता है, भले ही आपके पास एक returnबयान हो tryया न हो। एर्गो, आपको returnअंत में ब्लॉक के अंदर स्टेटमेंट द्वारा लौटाया गया मान मिलता है ।

मैंने इसे Ubuntu में 3.6.10 और क्रोम 6.0.472.63 दोनों के साथ परीक्षण किया। यह संभव है कि यह कोड अन्य ब्राउज़रों में भिन्न व्यवहार करे।


1

मैं यहाँ थोड़ा अलग जवाब देने जा रहा हूँ: हाँ, दोनों tryऔर finallyब्लॉक निष्पादित हो जाते हैं, और finallyएक फ़ंक्शन के लिए वास्तविक "वापसी" मूल्य पर पूर्वता लेता है। हालाँकि, ये रिटर्न मान हमेशा आपके कोड में उपयोग नहीं किए जाते हैं।

यहाँ पर क्यों:

  • नीचे दिया गया उदाहरण 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आपके ब्राउज़र में स्ट्रिंग दिखाएगा । ALSO, उदाहरण आपके कंसोल में त्रुटि दिखाएगा। res.send()समारोह कहा जाता है दो बार । यह एक फ़ंक्शन के साथ कुछ भी होगा। कोशिश-कैच-एंड-ब्लॉक इस तथ्य को अप्रशिक्षित आंख को बाधित करेगा, क्योंकि (व्यक्तिगत रूप से) मैं केवल 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इसके बजाय का उपयोग करें ।


0

अंत में ब्लॉक से लौटते हुए

यदि finally-block एक मान देता है, यह मान पूरे के रिटर्न मान हो जाता है try-catch-finallyबयान, परवाह किए बिना किसी भी returnमें बयान tryऔर catch-blocks

संदर्भ: developer.mozilla.org


-2

अंत में एक कोशिश पकड़ने ब्लॉक के अंत में हमेशा चलाने के लिए माना जाता है ताकि (विनिर्देशन द्वारा) आप क्यों झूठी वापसी कर रहे हैं। ध्यान रखें कि यह पूरी तरह से संभव है कि विभिन्न ब्राउज़रों का अलग-अलग कार्यान्वयन हो।


IE8, फ़ायरफ़ॉक्स 3.6 और क्रोम 6: सभी समान;)
बोनो

-3

इस बारे में क्या?

doubleReturn();

function doubleReturn() {
  let sex = 'boy';

  try {
    return sex;

    console.log('this never gets called...');
  } catch (e) {} finally {
    sex = 'girl'; 

    alert(sex);
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.