अनहेल्दी वादा अस्वीकृति क्या है?


203

कोणीय 2 सीखने के लिए, मैं उनके ट्यूटोरियल की कोशिश कर रहा हूं।

मुझे इस तरह एक त्रुटि मिल रही है:

(node:4796) UnhandledPromiseRejectionWarning: Unhandled promise rejection (r                                                                                                     ejection id: 1): Error: spawn cmd ENOENT
[1] (node:4796) DeprecationWarning: Unhandled promise rejections are deprecated.
In the future, promise rejections that are not handled will terminate the Node.
js process with a non-zero exit code.

मैं एसओ में विभिन्न प्रश्नों और उत्तरों से गुजरा, लेकिन यह पता नहीं लगा सका कि "अनहैंड्ड प्रॉमिस रिजेक्शन" क्या है।

क्या कोई मुझे केवल यह समझा सकता है कि यह क्या है और यह क्या Error: spawn cmd ENOENTहै, जब यह उठता है और मुझे इस चेतावनी से छुटकारा पाने के लिए क्या जाँच करनी है?


2
मुझे यह सवाल याद आ गया! मुझे इस चेतावनी के लिए बहुत खेद है कि यह भ्रामक है - हमने वास्तव में इसे नए Node.js में सुधार किया है और हम पूरी बात को जल्द ही बेहतर बना रहे हैं!
बेंजामिन ग्रुएनबाम

की संभावित डुप्लिकेट: stackoverflow.com/questions/38265963/…
क्रिस्तोफ़ रूसो

@BenjaminGruenbaum, क्या यह अभी तक तय है? मुझे नोड v12.16.1 पर वही त्रुटि मिली
बेबी डिस्टा

1
@ बेबेस्टा अच्छी तरह से, हम स्टैक ट्रेस के साथ अब एक बेहतर त्रुटि दिखाते हैं लेकिन हम अभी भी अनहेल्ड अस्वीकारों पर नोड को क्रैश नहीं करते हैं। हमें शायद ऐसा करने के लिए पीआर खोलने की जरूरत है।
बेंजामिन ग्रुएनबाम

जवाबों:


200

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

उदाहरण के लिए, फ़ंक्शन PTest () या तो वैश्विक वैरिएबल somevar के मूल्य के आधार पर एक वादे को हल या अस्वीकार करेगा

var somevar = false;
var PTest = function () {
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
            reject();
    });
}
var myfunc = PTest();
myfunc.then(function () {
     console.log("Promise Resolved");
}).catch(function () {
     console.log("Promise Rejected");
});

कुछ मामलों में, " अनहेल्दी वादा अस्वीकृति" संदेश तब भी आता है जब हमारे पास .catch (..) वादों के लिए लिखा जाता है। यह सब है कि आप अपना कोड कैसे लिखते हैं। हालांकि हम संभाल रहे हैं , निम्नलिखित कोड "अनहेल्ड वादा अस्वीकृति" उत्पन्न करेगा catch

var somevar = false;
var PTest = function () {
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
            reject();
    });
}
var myfunc = PTest();
myfunc.then(function () {
     console.log("Promise Resolved");
});
// See the Difference here
myfunc.catch(function () {
     console.log("Promise Rejected");
});

अंतर यह है कि आप .catch(...)चेन के रूप में नहीं बल्कि अलग-अलग हैं। किसी कारणवश जावास्क्रिप्ट इंजन इसे अन-हैंडल किए गए वादे अस्वीकृति के बिना वादे के रूप में मानता है।


4
यह काम करने लगता है, अगर आप myFunc = myFunct.then...दूसरे उदाहरण में जोड़ते हैं ।
आइंस्टीन

@ आइंस्टीन यह काम करने के लिए दिखाई देगा क्योंकि आप पहले उदाहरण में उसी श्रृंखला को फिर से बना रहे हैं:var x = foo(); x = x.then(...); x = x.catch(...)
randomsock

4
@einstein आपके अनचाहे उदाहरण में, जब आप कहते हैं "किसी कारण से जावा स्क्रिप्ट इंजन इसे अन-हैंडल किए गए वादे अस्वीकृति के बिना वादे के रूप में मानता है", तो क्या यह नहीं है और अपवाद को फेंक दिया जा सकता है .then(() => {...})जिसमें आप संभाल नहीं रहे हैं ? मुझे नहीं लगता कि यह वही काम कर रहा है जब आप उन्हें चेन करते हैं। क्या यह?
साइमन लेग

8
@DKG अपने दूसरे बिंदु के बारे में, के catchलिए एक वाक्यविन्यास चीनी है then(undefined, onRejected)। चूँकि आपके पहले से ही myfunc पर कॉल किया गया था और जो एक त्रुटि को ट्रिगर करता है, यह फिर से उसी वादे पर तब (अपरिभाषित, चालू) कॉल करने वाला नहीं है।
केविन ली ने

1
कहां बदलना है? मैं ईओण 3 का उपयोग कर रहा हूं जब मैंने आयनिक कॉर्डोवा बिल्ड और थोरिड कमांड को मारा, जिससे मुझे यह त्रुटि मिली।
सागर कोटेते

34

यह तब होता है जब एक निष्पादित कोड में एक अपवाद के Promiseसाथ पूरा किया जाता है .reject()या फेंक दिया जाता asyncथा और .catch()अस्वीकृति को नहीं संभालता था।

एक अस्वीकृत वादा एक अपवाद की तरह है जो अनुप्रयोग प्रविष्टि बिंदु की ओर बढ़ता है और मूल त्रुटि हैंडलर को उस आउटपुट का उत्पादन करने का कारण बनता है।

यह सभी देखें


कहां बदलना है? मैं ईओण 3 का उपयोग कर रहा हूं जब मैंने आयनिक कॉर्डोवा बिल्ड और थोरिड कमांड को मारा, जिससे मुझे यह त्रुटि मिली।
सागर कोडते

इस जानकारी के साथ बताना मुश्किल है। मेरा सुझाव है कि आप एक न्यूनतम प्रजनन बनाने की कोशिश करें और अपनी विशिष्ट स्थिति के लिए एक नया प्रश्न बनाएं।
गुंटर ज़ोचबॉयर

मैंने इसके लिए इनाम खोला है। कृपया इसे देखें stackoverflow.com/q/48145380/5383669
सागर कोडे

22

खारिज किए जाने के बाद वादे "संभाले" जा सकते हैं। यानी, एक कैच हैंडलर प्रदान करने से पहले एक वादे को अस्वीकार कर सकता है। यह व्यवहार मेरे लिए थोड़ा परेशान करने वाला है क्योंकि कोई भी लिख सकता है ...

var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });

... और इस मामले में, वादा चुपचाप खारिज कर दिया जाता है। यदि कोई कैच हैंडलर जोड़ना भूल जाता है, तो कोड चुपचाप त्रुटियों के बिना चलता रहेगा। इससे लिंग और सख्त कीड़े मिल सकते हैं।

Node.js के मामले में, इन अनहेल्ड प्रॉमिस रिजेक्ट को संभालने और समस्याओं की रिपोर्ट करने की बात है। यह मुझे ES7 async / प्रतीक्षा में लाता है। इस उदाहरण पर विचार करें:

async function getReadyForBed() {
  let teethPromise = brushTeeth();
  let tempPromise = getRoomTemperature();

  // Change clothes based on room temperature
  let temp = await tempPromise;
  // Assume `changeClothes` also returns a Promise
  if(temp > 20) {
    await changeClothes("warm");
  } else {
    await changeClothes("cold");
  }

  await teethPromise;
}

ऊपर दिए गए उदाहरण में, मान लीजिए कि दांत खारिज कर दिए गए थे (त्रुटि: टूथपेस्ट से बाहर!) पूरा होने से पहले। इस मामले में, दांतों की प्रतीक्षा तक एक अनहेल्ड प्रॉमिस रिजेक्शन होगा।

मेरा कहना यह है ... यदि हम अनहेल्ड प्रॉमिस रिजेक्शन को एक समस्या मानते हैं, तो प्रॉमिस जो बाद में एक वेट द्वारा नियंत्रित किया जाता है, अनजाने में बग के रूप में रिपोर्ट किया जा सकता है। फिर, यदि हम समस्याग्रस्त नहीं होने के लिए अनहेल्ड प्रॉमिस रिजेक्शन पर विचार करते हैं, तो वैध बग रिपोर्ट नहीं हो सकते हैं।

इस पर विचार?

यह यहां Node.js परियोजना में पाई गई चर्चा से संबंधित है:

डिफ़ॉल्ट अनहेल्ड रिजेक्शन डिटेक्शन बिहेवियर

यदि आप इस तरह से कोड लिखते हैं:

function getReadyForBed() {
  let teethPromise = brushTeeth();
  let tempPromise = getRoomTemperature();

  // Change clothes based on room temperature
  return Promise.resolve(tempPromise)
    .then(temp => {
      // Assume `changeClothes` also returns a Promise
      if (temp > 20) {
        return Promise.resolve(changeClothes("warm"));
      } else {
        return Promise.resolve(changeClothes("cold"));
      }
    })
    .then(teethPromise)
    .then(Promise.resolve()); // since the async function returns nothing, ensure it's a resolved promise for `undefined`, unless it's previously rejected
}

जब getReadyForBed का आह्वान किया जाता है, तो यह अंतिम रूप से अंतिम (नहीं लौटाया गया) वादा करेगा - जिसमें किसी अन्य वादे के समान "अनहेल्ड रिजेक्शन" त्रुटि होगी (इंजन के आधार पर, कुछ भी नहीं हो सकता है)। (मुझे यह बहुत अजीब लगता है कि आपका फ़ंक्शन कुछ भी वापस नहीं करता है, जिसका अर्थ है कि आपका async फ़ंक्शन अपरिभाषित के लिए एक वादा करता है।

अगर मैं अभी एक पकड़ के बिना एक वादा करता हूं, और एक बाद में जोड़ देता हूं, तो सबसे "अनहेल्ड रिजेक्शन त्रुटि" कार्यान्वयन वास्तव में चेतावनी को वापस ले लेंगे जब मैं बाद में इसे संभालता हूं। दूसरे शब्दों में, async / इंतजार किसी भी तरह से "अनहेल्ड रिजेक्शन" चर्चा को बदल नहीं सकता है जो मैं देख सकता हूं।

इस नुकसान से बचने के लिए कृपया इस तरह से कोड लिखें:

async function getReadyForBed() {
  let teethPromise = brushTeeth();
  let tempPromise = getRoomTemperature();

  // Change clothes based on room temperature
  var clothesPromise = tempPromise.then(function(temp) {
    // Assume `changeClothes` also returns a Promise
    if(temp > 20) {
      return changeClothes("warm");
    } else {
      return changeClothes("cold");
    }
  });
  /* Note that clothesPromise resolves to the result of `changeClothes`
     due to Promise "chaining" magic. */

  // Combine promises and await them both
  await Promise.all(teethPromise, clothesPromise);
}

ध्यान दें कि यह किसी भी अनहेल्ड वादा अस्वीकृति को रोकना चाहिए।


13

"पदावनत करना: बिना सोचे-समझे किए गए वादे को अस्वीकार कर दिया जाता है"

TLDR: एक वादा किया है resolveऔर reject, एक rejectको पकड़ने के बिना यह पदावनत करने के लिए है, तो आप कम से कम एक catchशीर्ष स्तर पर होगा।


2

मेरे मामले में वादे के साथ न तो अस्वीकार था और न ही हल, क्योंकि मेरे वचन समारोह ने एक अपवाद को फेंक दिया। यह गलती UnhandledPromiseRejectionWarning संदेश का कारण बनती है।


1

जब मैं एक वादे को तुरंत पूरा करता हूं, तो मैं एक अतुल्यकालिक फ़ंक्शन उत्पन्न करने जा रहा हूं। यदि फ़ंक्शन अच्छी तरह से चला जाता है, तो मैं RESOLVE को कॉल करता हूं तो प्रवाह RESOLVE हैंडलर में, THEN में जारी रहता है। यदि फ़ंक्शन विफल हो जाता है, तो REJECT को कॉल करके फ़ंक्शन को समाप्त करें फिर CATCH में प्रवाह जारी है।

NodeJs में अस्वीकृति हैंडलर पदावनत किए जाते हैं। आपकी त्रुटि सिर्फ एक चेतावनी है और मैंने इसे नोड के अंदर पढ़ा है। मुझे मिला।

DEP0018: अनहेल्दी वादा अस्वीकार

प्रकार: रनटाइम

अनचाहे वादे को अस्वीकार कर दिया जाता है। भविष्य में, अस्वीकार किए गए वादे को अस्वीकार कर दिया जाता है, जो एक शून्य-शून्य निकास कोड के साथ Node.js प्रक्रिया को समाप्त कर देगा।

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