javascript - फिर से पहले और बाद में पकड़ने का स्थान




जावास्क्रिप्ट सीखे (2)

मुझे डालने के बीच अंतर समझने में परेशानी होती है। फिर पहले एक नेस्टेड वादे के बाद।

वैकल्पिक 1:

test1Async(10).then((res) => {
  return test2Async(22)
    .then((res) => {
      return test3Async(100);
    }).catch((err) => {
      throw "ERROR AFTER THEN";
    });
}).then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});

वैकल्पिक 2:

test1Async(10).then((res) => {
   return test2Async(22)
     .catch((err) => {
        throw "ERROR BEFORE THEN";
      })
      .then((res) => {
        return test3Async(100);
      });
  }).then((res) => {
    console.log(res);
  }).catch((err) => {
    console.log(err);
  });

प्रत्येक फ़ंक्शन का व्यवहार निम्नानुसार है, नंबर <0 टेस्ट 1 असफल हो जाता है, यदि नंबर <0 है तो फेल है यदि संख्या > 10 और टेस्ट 3 विफल रहता है यदि संख्या 100 नहीं है। इस मामले में test2 केवल विफल हो रहा है।

मैंने चलाने की कोशिश की और test2Async को विफल बनाने के लिए, BEFORE और AFTER दोनों के बाद उसी तरह व्यवहार करता है और जो test3Async को निष्पादित नहीं कर रहा है। क्या कोई मुझे विभिन्न स्थानों पर पकड़ बनाने के लिए मुख्य अंतर समझा सकता है?

प्रत्येक फ़ंक्शन में I console.log('Running test X') यह जांचने के लिए कि क्या यह निष्पादित होता है।

यह प्रश्न उठता है कि पिछले धागे के कारण मैंने पोस्ट किया था कि कैसे नेस्टेड कॉलबैक को वादे में बदला जाए? । मुझे लगता है कि यह एक अलग समस्या है और किसी अन्य विषय को पोस्ट करने के लायक है।


तो, मूल रूप से आप पूछ रहे हैं कि इन दोनों के बीच क्या अंतर है (जहां p कुछ पिछले कोड से बनाया गया वादा है):

return p.then(...).catch(...);

तथा

return p.catch(...).then(...);

P के हल होने या अस्वीकार होने पर या तो अंतर होते हैं, लेकिन क्या वे अंतर मायने रखते हैं या नहीं, यह निर्भर करता है कि .catch() या .catch() हैंडलर के अंदर कोड क्या करता है।

क्या होता है जब p हल करता है:

पहली योजना में, जब p हल होता है, .then() हैंडलर कहा जाता है। यदि वह .then() हैंडलर या तो एक मान लौटाता है या एक और वादा करता है जो अंततः हल हो जाता है, तो .catch() हैंडलर छोड़ दिया जाता है। लेकिन, अगर .then() हैंडलर या तो एक वादे को फेंक देता है या वापस कर देता है, जो अंततः अस्वीकार कर देता है, तो .catch() हैंडलर मूल वादा p में अस्वीकार दोनों के लिए निष्पादित करेगा, लेकिन एक त्रुटि भी जो तब .then() तब) में होती है। हैंडलर।

दूसरी योजना में, जब p हल होता है, .then() हैंडलर कहा जाता है। यदि वह .then() हैंडलर या तो एक प्रतिज्ञा फेंकता है या वापस करता है, जो अंततः अस्वीकार कर देता है, तो .catch() हैंडलर उसे पकड़ नहीं सकता क्योंकि यह श्रृंखला में उसके पहले है।

तो, यह अंतर # 1 है। यदि .catch() हैंडलर AFTER है, तो यह .catch() हैंडलर के अंदर त्रुटियों को भी पकड़ सकता है।

क्या होता है जब p अस्वीकार करता है:

अब, पहली स्कीम में, यदि वादा p खारिज करता है, तो .catch() हैंडलर छोड़ दिया जाता है और .catch() हैंडलर को वैसे ही बुलाया जाएगा जैसा आप उम्मीद करेंगे। आप .catch() हैंडलर में क्या करते हैं यह निर्धारित करता है कि अंतिम परिणाम के रूप में क्या लौटाया गया है। यदि आप केवल .catch() हैंडलर से कोई मान .catch() या अंत में हल होने वाले वादे को वापस करते हैं, तो वादा श्रृंखला हल की हुई स्थिति में .catch() क्योंकि आप त्रुटि को "हैंडल" करते हैं और सामान्य रूप से लौटते हैं। यदि आप .catch() हैंडलर में अस्वीकार किए गए वादे को फेंकते हैं या लौटाते हैं, तो वापस किया गया वादा अस्वीकृत हो जाता है।

दूसरी योजना में, यदि वादा p अस्वीकार करता है, तो .catch() हैंडलर कहा जाता है। यदि आप एक सामान्य मान या एक वादा .catch() , जो अंततः .catch() हैंडलर (इस प्रकार "हैंडलिंग" त्रुटि) से हल होता है, तो वादा श्रृंखला स्विच किए गए राज्य और .catch() बाद हैंडलर पर स्विच करता है। बुलाया जाएगा।

तो यह अंतर # 2 है। यदि .catch() हैंडलर BEFORE है, तो यह त्रुटि को संभाल सकता है और .catch() .then() हैंडलर को अभी भी कॉल करने की अनुमति देता है।

कब कौन सा उपयोग करें:

पहली स्कीम का उपयोग करें यदि आप सिर्फ एक .catch() हैंडलर चाहते हैं जो मूल वादा p या .catch() हैंडलर में त्रुटियों को पकड़ सकता है और p से अस्वीकार को .catch() हैंडलर को छोड़ देना चाहिए।

दूसरी योजना का उपयोग करें यदि आप मूल वादा p और शायद (शर्तों के आधार पर) में त्रुटियों को पकड़ने में सक्षम होना चाहते हैं, तो वादा श्रृंखला को हल करने के लिए जारी रखने की अनुमति दें, इस प्रकार .then() हैंडलर को निष्पादित करना।

दूसरा विकल्प

दोनों कॉलबैक का उपयोग करने के लिए एक और विकल्प है जिसे आप .then() में पास कर सकते हैं:

 p.then(fn1, fn2)

यह गारंटी देता है कि fn1 या fn2 से केवल एक को कभी भी कॉल किया जाएगा। यदि p हल करता है, तो fn1 कहा जाएगा। यदि p अस्वीकार करता है, तो fn2 कहा जाएगा। fn2 में परिणाम का कोई परिवर्तन कभी भी fn2 को कॉल नहीं कर सकता है या इसके विपरीत। इसलिए, यदि आप पूरी तरह से सुनिश्चित करना चाहते हैं कि आपके दो हैंडलर में से केवल एक को ही बुलाया जाए, भले ही हैंडलर में क्या होता है तो आप p.then(fn1, fn2) उपयोग कर सकते हैं।


jfriend00 का उत्तर उत्कृष्ट है, लेकिन मुझे लगा कि अनुरूप तुल्यकालिक कोड को जोड़ना एक अच्छा विचार होगा।

return p.then(...).catch(...);

तुल्यकालिक के समान है:

try {
  iMightThrow() // like `p`
  then()
} catch (err) {
  handleCatch()
}

यदि iMightThrow() नहीं फेंकता है, then() कहा जाएगा। यदि यह फेंक देता है (या यदि then() स्वयं फेंकता है), तो handleCatch() कहा जाएगा। ध्यान दें कि catch ब्लॉक का उस पर कोई नियंत्रण नहीं है या नहीं।

दूसरी ओर,

return p.catch(...).then(...);

तुल्यकालिक के समान है:

try {
  iMightThrow()
} catch (err) {
  handleCatch()
}

then()

इस स्थिति में, यदि iMightThrow() नहीं फेंकता है, then() निष्पादित करेगा। यदि यह फेंक देता है, तो इसे handleCatch() then() तय करना होगा कि अगर then() कहा जाता है, क्योंकि अगर handleCatch() पुनर्विचार करता है, तो then() को कॉल नहीं किया जाएगा, क्योंकि अपवाद को तुरंत कॉल करने के लिए फेंक दिया जाएगा। यदि handleCatch() इनायत से मुद्दे को संभाल सकता है, then() कहा जाएगा।





bluebird