[javascript] 처리되지 않은 약속 거부 란 무엇입니까?

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

나는 SO에서 다른 질문과 답변을 겪었지만 “처리되지 않은 약속 거부”가 무엇인지 알 수 없었습니다.

누구든지 단순히 그것이 무엇 Error: spawn cmd ENOENT이고 무엇 이고 언제 발생하는지, 그리고이 경고를 제거하기 위해 확인해야 할 것을 설명 할 수 있습니까?



답변

이 오류의 근원은 각각의 모든 약속이 약속 거부를 처리해야한다는 사실에 있습니다. 즉 .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(...)체인으로 취급하지 않고 별개로 처리한다는 것 입니다. 어떤 이유로 JavaScript 엔진은 처리되지 않은 약속 거부없이 약속으로 취급합니다.


답변

이것은 a Promise로 완료 .reject()되거나 async실행 코드 에서 예외가 발생 .catch()하고 거부를 처리 하지 않은 경우입니다.

거부 된 약속은 응용 프로그램 진입 점을 향해 버블 링되어 근본 오류 처리기가 해당 출력을 생성하는 예외와 같습니다.

또한보십시오


답변

약속은 거부 된 후에 “처리”될 수 있습니다. 즉, catch 처리기를 제공하기 전에 promise의 거부 콜백을 호출 할 수 있습니다. 이 행동은 쓸 수 있기 때문에 조금 귀찮습니다 …

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

…이 경우 약속은 자동으로 거부됩니다. 캐치 핸들러 추가를 잊어 버린 경우에도 코드는 자동으로 오류없이 계속 실행됩니다. 이로 인해 느리고 찾기 어려운 버그가 발생할 수 있습니다.

Node.js의 경우, 이러한 처리되지 않은 Promise 거부를 처리하고 문제를보고하는 이야기가 있습니다. 이로 인해 ES7 async / await가 나타납니다. 이 예제를 고려하십시오.

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

위의 예에서 getRoomTemperature가 충족되기 전에 teethPromise가 거부되었다고 가정합니다 (오류 : 치약에서!). 이 경우 teethPromise를 기다릴 때까지 처리되지 않은 Promise 거부가 발생합니다.

내 요점은 … 우리가 처리되지 않은 약속 거부를 문제로 생각하면 나중에 대기에 의해 처리되는 약속은 실수로 버그로보고 될 수 있습니다. 처리되지 않은 약속 거부가 문제가되지 않는 것으로 간주하면 합법적 인 버그가보고되지 않을 수 있습니다.

이것에 대한 생각?

이것은 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 / await는 내가 볼 수있는 “처리되지 않은 거부”토론을 변경하지 않습니다.

이 함정을 피하려면 다음과 같이 코드를 작성하십시오.

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

이는 처리되지 않은 약속 거부를 방지해야합니다.


답변

“DeprecationWarning : 처리되지 않은 약속 거부는 더 이상 사용되지 않습니다”

TLDR :의 약속이 resolvereject하는 일을 reject당신이 가지고 적어도 할 것이다, 그래서이되지 않습니다 처리하는 캐치없이 catch최상위 수준.


답변

필자의 경우 Promise 함수에서 예외가 발생했기 때문에 거부하지 않고 약속을 지키지 않은 Promise였습니다. 이 실수는 UnhandledPromiseRejectionWarning 메시지를 발생시킵니다.


답변

약속을 인스턴스화하면 비동기 함수를 생성합니다. 함수가 제대로 진행되면 RESOLVE를 호출하면 THEN의 RESOLVE 처리기에서 흐름이 계속됩니다. 함수가 실패한 경우 REJECT를 호출하여 함수를 종료하면 CATCH에서 플로우가 계속됩니다.

NodeJ에서는 거부 처리기가 더 이상 사용되지 않습니다. 귀하의 오류는 경고 일 뿐이며 node.js github에서 읽습니다. 나는 이것을 찾았다.

DEP0018 : 처리되지 않은 약속 거부

유형 : 런타임

처리되지 않은 약속 거부는 더 이상 사용되지 않습니다. 앞으로 처리되지 않은 약속 거부는 0이 아닌 종료 코드로 Node.js 프로세스를 종료합니다.


답변