web-dev-qa-db-fra.com

Qu'est-ce qu'un rejet de promesse non géré?

Pour apprendre Angular 2, j'essaie leur tutoriel.

Je reçois une erreur comme celle-ci:

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

J'ai parcouru différentes questions et réponses dans SO mais je n'ai pas pu déterminer ce qu'est un "rejet de promesse non gérée".

Quelqu'un peut-il simplement m'expliquer ce que c'est et aussi ce que _Error: spawn cmd ENOENT_ est, quand il se produit et ce que je dois vérifier pour me débarrasser de cet avertissement?

148

L’origine de cette erreur réside dans le fait que chaque promesse est censée gérer le rejet d’une promesse, c’est-à-dire avoir un . Catch (...) (...) . vous pouvez éviter la même chose en ajoutant . catch (...) à une promesse dans le code, comme indiqué ci-dessous.

par exemple, la fonction PTest () résoudra ou rejettera une promesse basée sur la valeur d'une variable globale 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");
});

Dans certains cas, le message "rejet de promesse non gérée" vient même si nous avons .catch (..) écrit pour promesses . Tout dépend de la manière dont vous écrivez votre code. Le code suivant générera "rejet de promesse non gérée" même si nous traitons 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");
});

La différence est que vous ne gérez pas .catch(...) comme une chaîne, mais séparément. Pour quelque raison que ce soit, le moteur JavaScript la traite comme une promesse sans rejet non traité.

158
Daksh

Cela se produit lorsqu'un Promise est complété par .reject() ou qu'une exception a été générée dans un code async exécuté et qu'aucun .catch() ne gère le rejet.

Une promesse refusée est comme une exception qui bouillonne vers le point d'entrée de l'application et force le gestionnaire d'erreurs racine à générer cette sortie.

Voir également

31

Les promesses peuvent être "traitées" après leur rejet. C'est-à-dire que l'on peut appeler le rappel de rejet d'une promesse avant de fournir un gestionnaire de capture. Ce comportement me gêne un peu car on peut écrire ...

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

... et dans ce cas, la promesse est rejetée en silence. Si l'on oublie d'ajouter un gestionnaire d'interception, le code continuera de s'exécuter en silence, sans erreur. Cela pourrait conduire à des bogues persistants et difficiles à trouver.

Dans le cas de Node.js, il est question de gérer ces rejets non pris en charge et de signaler les problèmes. Cela m'amène à ES7 async/wait. Considérons cet exemple:

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

Dans l'exemple ci-dessus, supposons que les actions de promotionPeinture soient rejetées (erreur: il ne reste plus de dentifrice!) Avant l'exécution de getRoomTemperature. Dans ce cas, il y aurait un rejet non géré de la promesse jusqu'à l'attente de dents.

Mon argument est le suivant ... si nous considérons que le rejet des promesses non gérées est un problème, les promesses gérées ultérieurement par une attente risquent d’être par inadvertance signalées comme des bogues. Là encore, si nous considérons que les rejets de promesses non gérées ne sont pas problématiques, les bogues légitimes risquent de ne pas être signalés.

Des pensées à ce sujet?

Ceci est lié à la discussion trouvée dans le projet Node.js ici:

Comportement par défaut de détection de rejet non géré

si vous écrivez le code de cette façon:

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
}

Lorsque getReadyForBed est appelé, il crée de manière synchrone la promesse finale (non retournée) - qui aura la même erreur de "rejet non gérée" que toute autre promesse (peut ne rien être, bien sûr, en fonction du moteur). (Je trouve cela très étrange que votre fonction ne retourne rien, ce qui signifie que votre fonction asynchrone produit une promesse pour indéfini.

Si je fais une promesse maintenant sans attraper et que j'en ajoute une plus tard, la plupart des implémentations "d'erreur de rejet non gérée" retireront en réalité l'avertissement lorsque je le traiterai plus tard. En d'autres termes, async/wait n'altère en rien la discussion sur le "rejet non géré".

pour éviter ce piège, veuillez écrire le code de cette façon:

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

Notez que cela devrait empêcher tout rejet de promesse non géré.

20
anis programmer

"DeprecationWarning: nhandled les rejets de promesses sont obsolètes"

TLDR: Une promesse a resolve et reject, faire un reject sans accroc pour le gérer est obsolète. Vous devrez donc au moins avoir un catch au plus haut niveau. .

9
Christophe Roussy

Dans mon cas, Promise était sans rejet ni résolution, car ma fonction Promise générait une exception. Cette erreur provoque le message UnhandledPromiseRejectionWarning.

0
Diniz

Lorsque j'instancie une promesse, je vais générer une fonction asynchrone. Si la fonction se passe bien, j'appelle RESOLVE, puis le flux continue dans le gestionnaire RESOLVE, dans THEN. Si la fonction échoue, fermez-la en appelant REJECT, puis le flux continue dans CATCH.

Dans NodeJs sont obsolètes le gestionnaire de rejet. Votre erreur est juste un avertissement et je le lis à l'intérieur de node.js github. J'ai trouvé ça.

DEP0018: Rejets de promesses non gérées

Type: Runtime

Les rejets de promesses non gérées sont obsolètes. À l'avenir, les rejets de promesses qui ne sont pas gérés termineront le processus Node.js avec un code de sortie non nul.

0
koλzar