वादा करने में त्रुटि को पकड़ना


93

मुझे एक ट्यूटोरियल में निम्न कोड मिला:

promise.then(function(result){
    //some code
}).catch(function(error) {
    throw(error);
});

मैं थोड़ा भ्रमित हूं: क्या कॉल कॉल कुछ भी पूरा करती है? यह मुझे लगता है कि इसका कोई प्रभाव नहीं है, क्योंकि यह केवल उसी त्रुटि को फेंकता है जिसे पकड़ा गया था। मैं इस पर आधारित है कि कैसे एक नियमित रूप से कोशिश / पकड़ काम करता है।


क्या आप ट्यूटोरियल के लिए एक लिंक प्रदान कर सकते हैं? शायद वहाँ अतिरिक्त संदर्भ है कि उपयोगी होगा ...
इगोर

@ मैं नहीं कर सकता, यह Pluralsight पर है। क्या यह संभवतः तर्क को सौंपने में कुछ त्रुटि के लिए एक प्लेसहोल्डर है?
टायलर डर्डन

यही कारण है कि मैं अनुमान लगाता हूं कि यह अधिक कुछ नहीं करता है, फिर कॉल करने वाले के साथ त्रुटि पास करें जो कि शुरू करने के लिए पकड़ नहीं होने से भी पूरा हो सकता है।
इगोर

1
@TylerDurden मुझे संदेह है कि आप इसके बारे में सही हैं कि यह एक प्लेसहोल्डर है।
जारेड स्मिथ

@TylerDurden, मुझे यह भी अनुमान है कि यह एक प्लेसहोल्डर है। शायद त्रुटियों को प्रारूपित / सामान्य करने का तरीका प्रदर्शित करने की कोशिश कर रहा है। मूल रूप से वादा-समकक्ष try { ... }catch(error){ throw new Error("something went wrong") }। या यह दिखाने के लिए कि वादे और त्रुटियाँ संगत हैं (कम से कम उस तरह से चारों ओर) । लेकिन इसके वर्तमान कार्यान्वयन में यह सिर्फ बेवकूफी है। आप सही कह रहे हैं, यह कुछ भी नहीं करता है और यह भी एक हुक की तरह नहीं है जिसे आप OOP में शामिल करेंगे ताकि इसे एक विरासत वर्ग में अधिलेखित करने में सक्षम किया जा सके। जैसे ही वह कुछ करता है मैं कैच-ब्लॉक को जोड़ देता हूं, लेकिन ऐसा नहीं है, न कि केवल एक प्लेसहोल्डर के रूप में।
थॉमस

जवाबों:


130

जैसा कि आप दिखाते हैं कि नग्न पकड़ने और फेंकने का कोई मतलब नहीं है। यह कोड और धीमी गति से निष्पादन को छोड़कर कुछ भी उपयोगी नहीं है। इसलिए, यदि आप जा रहे हैं .catch()और पुनर्खरीद कर रहे हैं, तो कुछ ऐसा होना चाहिए जो आप करना चाहते हैं .catch(), अन्यथा आपको .catch()पूरी तरह से हटा देना चाहिए ।

उस सामान्य संरचना के लिए सामान्य बिंदु यह है कि जब आप किसी चीज को निष्पादित करना चाहते हैं .catch()जैसे कि त्रुटि को लॉग करें या कुछ स्थिति (जैसे क्लोज फाइल्स) को साफ करें, लेकिन आप चाहते हैं कि वादे का सिलसिला जारी रहे।

promise.then(function(result){
    //some code
}).catch(function(error) {
    // log and rethrow 
    console.log(error);
    throw error;
});

एक ट्यूटोरियल में, यह सिर्फ लोगों को दिखाने के लिए हो सकता है जहां वे त्रुटियों को पकड़ सकते हैं या त्रुटि को संभालने की अवधारणा को पढ़ाने के लिए, फिर इसे हटा सकते हैं।


पकड़ने और पुनर्वसन करने के कुछ उपयोगी कारण इस प्रकार हैं:

  1. आप त्रुटि लॉग करना चाहते हैं , लेकिन अस्वीकार किए गए वादे की श्रृंखला को बनाए रखें।
  2. आप त्रुटि को कुछ अन्य त्रुटि (अक्सर श्रृंखला के अंत में आसान त्रुटि प्रसंस्करण के लिए) में बदलना चाहते हैं । इस मामले में, आप एक अलग त्रुटि को हटा देंगे।
  3. वादा श्रृंखला जारी रहने से पहले आप प्रसंस्करण का एक गुच्छा करना चाहते हैं (जैसे कि करीब / मुक्त संसाधन) लेकिन आप चाहते हैं कि वादा श्रृंखला अस्वीकृत रहे।
  4. यदि आप एक विफलता है तो वादा श्रृंखला में इस बिंदु पर डीबगर के लिए एक ब्रेकपॉइंट लगाने के लिए एक स्पॉट चाहते हैं ।

लेकिन, कैच हैंडलर में कोई अन्य कोड के साथ एक ही कैच और एक ही एरर के रीथ्रो को कोड के सामान्य चलने के लिए कुछ भी उपयोगी नहीं होता है।


मेरी राय से यह noe \ t अच्छा उदाहरण है। इस तरह के दृष्टिकोण से आप आसानी से 1 त्रुटि के लिए कई लॉगिंग प्राप्त कर सकते हैं। जावा में आप बस throw new Exception(periousException);मुझे नहीं पता हो सकता है कि जावास्क्रिप्ट नेस्टेड त्रुटि का समर्थन करता है, लेकिन वैसे भी "लॉग एंड थ्रो" बुरा अभ्यास है।
चेरी

27
@Cherry - आप यह नहीं कह सकते कि यह सामान्य रूप से एक बुरा अभ्यास है। ऐसे समय होते हैं जब कोई मॉड्यूल अपनी त्रुटियों को अपने तरीके से लॉग इन करना चाहता है और ऐसा करने का एक तरीका है। इसके अलावा, मैं यह सिफारिश नहीं कर रहा हूँ, मैं बस समझा रहा हूँ कि वहाँ कोई कारण नहीं है .catch()और एक ही त्रुटि को पकड़ के अंदर फेंक दें जब तक कि आप किसी और में SOMETHING न करें .catch()। यही इस उत्तर की बात है।
at१

आम तौर पर अपवादों को अमूर्तता के स्तर पर फिट होना चाहिए। उदाहरण के लिए एक db संबंधित अपवाद को पकड़ने के लिए इसकी पूरी तरह से ठीक है, और एक "सेवा" अपवाद की तरह कुछ फेंक दें जो कॉलर द्वारा नियंत्रित किया जाएगा। यह विशेष रूप से उपयोगी है जब आप निम्न-स्तरीय अपवादों के बारे में विवरणों को उजागर करने के लिए नहीं करते हैं
मैक्सट्रियलफायर

3
पकड़ने के लिए और (कभी-कभी) फेंकने का एक और अच्छा कारण एक विशिष्ट त्रुटि को संभालना है, लेकिन बाकी सब कुछ को फिर से उखाड़ फेंकना है।
जैस्पर

2
@SimonZyx - हां, उसके .finally()लिए बहुत उपयोगी हो सकता है, लेकिन कभी-कभी गैर-त्रुटि पथ में संसाधनों का पहले से ही ध्यान रखा जाता है इसलिए .catch()अभी भी उन्हें बंद करने की जगह है। यह वास्तव में स्थिति पर निर्भर करता है।
jfriend00

16

दोनों .then()और .catch()तरीके प्रोमिस लौटते हैं, और यदि आप किसी हैंडलर में एक्सेप्शन फेंकते हैं, तो लौटाया गया वादा अस्वीकार कर दिया जाता है और एक्सेप्शन अगले रिजेक्ट हैंडलर में पकड़ा जाएगा।

निम्नलिखित कोड में, हम पहले में एक अपवाद फेंकते हैं .catch(), जो दूसरे में पकड़ा जाता है .catch():

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');
        
    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
});

दूसरा .catch()वादा किया गया वादा पूरा होता है, जिसे .then()हैंडलर कहा जा सकता है:

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');
        
    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
})
.then(() => {
    console.log('Show this message whatever happened before');
});

उपयोगी संदर्भ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch

उम्मीद है की यह मदद करेगा!


4

यदि आप catchविधि कॉल को पूरी तरह से छोड़ देते हैं तो कोई महत्वपूर्ण अंतर नहीं है ।

केवल एक चीज जो इसे जोड़ती है वह एक अतिरिक्त माइक्रोटैस्क है, जिसका अर्थ है कि आप वादे की अस्वीकृति को नोटिस करेंगे बाद में उस वादे के लिए मामला है जो catchखंड के बिना विफल हो जाता है।

अगला स्निपेट यह प्रदर्शित करता है:

var p;
// Case 1: with catch
p = Promise.reject('my error 1')
       .catch(function(error) {
          throw(error);
       });

p.catch( error => console.log(error) );
// Case 2: without catch
p = Promise.reject('my error 2');

p.catch( error => console.log(error) );

ध्यान दें कि पहली से पहले दूसरी अस्वीकृति कैसे बताई जाती है। वह केवल अंतर के बारे में है।


3

तो ऐसा लगता है कि आपका सवाल है, "वादा श्रृंखला में, .catch()विधि क्या करती है?"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

फेंक बयान "बंद हो जाएगा (फेंकने के बाद के बयान निष्पादित नहीं किए जाएंगे), और कॉल स्टैक में पहले कैच ब्लॉक को नियंत्रित किया जाएगा। यदि कॉल फ़ंक्शन के बीच कोई कैच ब्लॉक मौजूद नहीं है, तो प्रोग्राम समाप्त हो जाएगा।"

वादे की श्रृंखला में, .then()विधि कुछ प्रकार के डेटा चंक को वापस कर देगी। ठग की यह वापसी वादा पूरा करेगी। डेटा का सफल रिटर्न वादा पूरा करता है। आप .catch()उसी तरीके से विधि के बारे में सोच सकते हैं । .catch()हालाँकि, असफल डेटा को पुनः प्राप्त करेगा। फेंक बयान वादा पूरा करता है। कभी-कभी, आपको डेवलपर्स का उपयोग दिखाई देगा .catch((err) => {console.log(err))} जो वादा श्रृंखला को भी पूरा करेगा।


0

आपको वास्तव में इसे फेंकने की आवश्यकता नहीं है, बस Promise.catch को खाली छोड़ दें अन्यथा यह अस्वीकार को संभालने के रूप में विचार करेगा और फिर कोड को एक कोशिश में पकड़ लेगा और यह स्वचालित रूप से त्रुटि को पकड़ लेगा जो नीचे से गुजर रहा है।

try{
  promise.then(function(result){
    //some code
  }).catch(function(error) {
    //no need for re throwing or any coding. but leave this as this otherwise it will consider as un handled
  });
}catch(e){
  console.log(e);
  //error can handle in here
}

0

वादे की श्रृंखला में, इसका उपयोग करना बेहतर है। बैच

ex in function f2: .then (...)। catch (e => reject (e));

  • test1 - try catch के साथ
  • test2 - बिना कोशिश या .catch के
  • test3 - .catch के साथ

function f1() {
    return new Promise((resolve, reject) => {
        throw new Error('test');
    });
}

function f2() {
    return new Promise((resolve, reject) => {
        f1().then(value => {
            console.log('f1 ok ???');
        }).catch(e => reject(e));
    });
}

function test1() {
    console.log('test1 - with try catch - look in F12');
    try {
      f2().then(() => { // Uncaught (in promise) Error: test
        console.log('???'); });
    } catch (e) {
      console.log('this error dont catched');
    }
}

function test2() {
    console.log('test2 - without try or .catch - look in F12');
    f2(); // Uncaught (in promise) Error: test
}

function test3() {
  console.log('test3 - with .catch');
  f2().then(value => {
    console.log('??');
  }).catch(e => {
    console.log(' now its ok, error ', e);
  })
}

setTimeout(() => { test1(); 
  setTimeout(() => { test2(); 
    setTimeout(() => { test3(); 
    }, 100);
  }, 100);
}, 100);

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