Wat is een onverhandelde belofte afwijzing?

Voor het leren van hoek 2, probeer ik hun tutorial.

Ik krijg een foutmelding als deze:

(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.

Ik ging door verschillende vragen en antwoorden in, maar kon niet achterhalen wat een “ongeoordeelde belofte-afwijzing” is.

Kan iemand me gewoon verklaren wat het is en ook wat Error: spawn cmd ENOENTis, wanneer het ontstaat en wat ik moet controleren om van deze waarschuwing af te komen?


Antwoord 1, Autoriteit 100%

De oorsprong van deze fout ligt in het feit dat elke belofte naar verwachting zal omgaan met belofte-afwijzing, d.w.z. een .catch (…) hebben. U kunt hetzelfde vermijden door toe te voegen. Catch (…) aan een belofte in de code zoals hieronder vermeld.

De functie PTEST () zal bijvoorbeeld een belofte oplossen of weigeren op basis van de waarde van een globale variabele 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");
});

In sommige gevallen komt het bericht “onverwerkte belofte afwijzing”zelfs als we .catch(..) hebben geschreven voor beloften. Het gaat erom hoe je je code schrijft. De volgende code genereert ‘onverwerkte belofte afwijzing’, ook al verwerken we 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");
});

Het verschil is dat je .catch(...)niet als ketting maar als apart behandelt. Om de een of andere reden behandelt de JavaScript-engine het als een belofte zonder onverwerkte afwijzing van beloften.


Antwoord 2, autoriteit 19%

Dit is wanneer een Promisewordt voltooid met .reject()of er een uitzondering is opgetreden in een asyncuitgevoerde code en geen .catch()heeft de afwijzing wel afgehandeld.

Een afgewezen belofte is als een uitzondering die opborrelt naar het toegangspunt van de toepassing en ervoor zorgt dat de root-fouthandler die uitvoer produceert.

Zie ook


Antwoord 3, Autoriteit 10%

Beloften kunnen worden “behandeld” nadat ze worden afgewezen. Dat wil zeggen, men kan een belofte nalaten noemen voordat u een catch-handler biedt. Dit gedrag is een beetje lastig voor mij omdat men kan schrijven …

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

… en in dit geval wordt de belofte stil afgewezen. Als iemand vergeet om een ​​catch-handler toe te voegen, blijft de code zwijgend zonder fouten. Dit kan leiden tot slepende en moeilijk te vinden bugs.

In het geval van NODE.JS is er sprake van het afhandelen van deze niet-verwerkte belofingsafwijzingen en het melden van de problemen. Dit brengt me naar ES7 async / wacht. Overweeg dit voorbeeld:

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;
}

In het bovenstaande voorbeeld, stel dat ToetsPromise werd afgewezen (FOUT: Out of Tandpasta!) Voordat GetroomTemperatuur is voldaan. In dit geval zou er een niet-verwerkte belofte-afwijzing zijn totdat het op het gebied van tandpromise wacht.

Mijn punt is dit… als we onverwerkte afwijzingen van beloften als een probleem beschouwen, kunnen beloften die later worden afgehandeld door een wachtende onbedoeld als bugs worden gerapporteerd. Aan de andere kant, als we onverwerkte afwijzingen van beloften niet als problematisch beschouwen, worden legitieme bugs mogelijk niet gerapporteerd.

Gedachten hierover?

Dit is gerelateerd aan de discussie in het Node.js-project hier:

Standaard niet-verwerkte detectie van afwijzingen

als je de code op deze manier schrijft:

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
}

Wanneer getReadyForBed wordt aangeroepen, zal het synchroon de laatste (niet geretourneerde) belofte maken – die dezelfde “onverwerkte afwijzing”-fout zal hebben als elke andere belofte (kan natuurlijk niets zijn, afhankelijk van de engine). (Ik vind het heel vreemd dat je functie niets retourneert, wat betekent dat je asynchrone functie een belofte produceert voor undefined.

Als ik nu een belofte doe zonder een vangst en er later een toevoeg, zullen de meeste implementaties van “onverwerkte afwijzingsfout” de waarschuwing intrekken wanneer ik deze later afhandel. Met andere woorden, async/wait verandert niets aan de “onverwerkte afwijzing”-discussie op een manier die ik kan zien.

om deze valkuil te vermijden, schrijf de code op deze manier:

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);
}

Merk op dat dit elke onverwerkte afwijzing van beloften zou moeten voorkomen.


Antwoord 4, autoriteit 6%

“Beëindigingwaarschuwing: Onverwerkteafwijzingen van beloften worden beëindigd”

TLDR: Een belofte heeft resolveen reject, het doen van een rejectzonder een catch om het af te handelen is afgekeurd, dus u moet tenminste een catchop het hoogste niveau hebben.


Antwoord 5

In mijn geval was Promise zonder afwijzing noch resolutie, omdat mijn Promise-functie een uitzondering veroorzaakte. Deze fout veroorzaakt een UnhandledPromiseRejectionWarning-bericht.


Antwoord 6

Als ik een belofte maak, ga ik een asynchrone functie genereren. Als de functie goed gaat, roep ik de RESOLVE aan, dan gaat de stroom verder in de RESOLVE-handler, in de THEN. Als de functie faalt, beëindig dan de functie door REJECT aan te roepen en de stroom gaat verder in de CATCH.

In NodeJ’s is de afwijzingshandler verouderd. Uw fout is slechts een waarschuwing en ik lees het in node.js github. Ik heb dit gevonden.

DEP0018: onverwerkte afwijzingen van beloften

Type: Runtime

Onverwerkte afwijzingen van toezeggingen worden afgekeurd. In de toekomst zullen afwijzingen van beloften die niet worden afgehandeld, het Node.js-proces beëindigen met een exitcode die niet nul is.


Antwoord 7

Ik had een soortgelijk probleem gehad met NodeJS, waarbij de boosdoener een forEach-lus was. Merk op dat forEach een synchrone functie is (NIET asynchroon). Daarom negeert het gewoon de teruggekeerde belofte.
De oplossing was om in plaats daarvan een for-of-lus te gebruiken:
Code waar ik de fout kreeg:

UnhandledPromiseRejectionWarning: Onverwerkte afwijzing van belofte. Deze fout is ontstaan door ofwel een asynchrone functie binnen te gooien zonder een catch-blok, of door een belofte te verwerpen die niet is afgehandeld met .catch()

is als volgt:

permissionOrders.forEach( async(order) => {
        const requestPermissionOrder = new RequestPermissionOrderSchema({
            item: order.item,
            item_desc: order.item_desc,
            quantity: order.quantity,
            unit_price: order.unit_price,
            total_cost: order.total_cost,
            status: order.status,
            priority: order.priority,
            directOrder: order.directOrder
        });
        try {
            const dat_order = await requestPermissionOrder.save();
            res.json(dat_order);
        } catch(err){
            res.json({ message : err});
        }
    });

De oplossing voor het bovenstaande probleem is als volgt:

for (let order of permissionOrders){
        const requestPermissionOrder = new RequestPermissionOrderSchema({
            item: order.item,
            item_desc: order.item_desc,
            quantity: order.quantity,
            unit_price: order.unit_price,
            total_cost: order.total_cost,
            status: order.status,
            priority: order.priority,
            directOrder: order.directOrder
        });
        try {
            const dat_order = await requestPermissionOrder.save();
            res.json(dat_order);
        } catch(err){
            res.json({ message : err});
        }
    };

Antwoord 8

Probeer de verbinding niet te sluiten voordat u gegevens naar uw database verzendt. Verwijder client.close();uit je code en het zal goed werken.

Other episodes