UFO ET IT

거부 호출 대 오류 발생이있는 약속 생성자

ufoet 2021. 1. 6. 20:02
반응형

거부 호출 대 오류 발생이있는 약속 생성자


다음 코드에서 :

var p1 = new Promise(function (resolve, reject) {
    throw 'test1';
});

var p2 = new Promise(function (resolve, reject) {
    reject('test2');
});

p1.catch(function (err) {
    console.log(err); // test1
});

p2.catch(function (err) {
    console.log(err); // test2
});

사용 사이의 차이가 reject(에 p2로부터) PromiseAPI 및 (에서 오류를 던지는 p1사용)는 throw?

정확히 똑같나요?

같은 경우 reject콜백이 필요한 이유는 무엇입니까?


사용 사이의 차이가 reject(에 p2로부터) PromiseAPI 및 (에서 오류를 던지는 p1사용)는 throw?

네, 비동기 적으로 사용할 수 없지만 은 콜백입니다. 예를 들어, 일부 시간 초과 :throwreject

new Promise(_, reject) {
    setTimeout(reject, 1000);
});

정확히 똑같나요?

아니요, 적어도 다른 코드가 귀하의 진술을 따르는 경우는 아닙니다. throw즉시 리졸버 함수를 완료하고, 호출 reject은 프로 미스를 거부 된 것으로 "표시"한 후 정상적으로 실행을 계속합니다.

또한 throw개체에 오류가 발생 하면 엔진이 다른 예외 디버깅 정보를 제공 할 수 있습니다.

당신의 구체적인 예를 들어, 당신은 옳고 외부 p1p2구별 할 수 없습니다.


아니요, 없습니다. 둘은 완전히 동일합니다. 유일한 차이점과 필요한 이유는 reject비동기 적으로 거부해야하는 경우입니다. 예를 들어 콜백 기반 API를 변환하는 경우 비동기 오류를 신호해야 할 수 있습니다.

var p = new Promise(function(resolve, reject){
    someCallbackApi(function(err, data){
        if(err) reject(err); // CAN'T THROW HERE, non promise context, async.
        else resolve(data);
    });
});

나는 이것이 조금 늦었다는 것을 알고 있지만, 나는이 답변 중 어느 것도 내가 이것을 발견했을 때 내가 가진 질문에 완전히 답하지 않는다고 생각합니다. 여기에 더 완전한 예가 있습니다.

var p1 = new Promise(function (resolve, reject) {
    throw 'test 1.1'; //This actually happens
    console.log('test 1.1.1'); //This never happens
    reject('test 1.2'); //This never happens because throwing an error already rejected the promise
    console.log('test 1.3'); //This never happens
});

var p2 = new Promise(function (resolve, reject) {
    reject('test 2.1'); //This actually happens
    console.log('test 2.1.1'); //This happens BEFORE the Promise is rejected because reject() is a callback
    throw 'test 2.2'; //This error is caught and ignored by the Promise
    console.log('test 2.3'); //This never happens
});

var p3 = new Promise(function (resolve, reject) {
    setTimeout(function() { reject('test 3.1');}, 1000); //This never happens because throwing an error already rejected the promise
    throw('test 3.2'); //This actually happens
    console.log('test 3.3'); //This never happens
});

var p4 = new Promise(function (resolve, reject) {
    throw('test 4.1'); //This actually happens
    setTimeout(function() { reject('test 4.2');}, 1000); //This never happens because throwing an error already rejected the promise
    console.log('test 4.3'); //This never happens
});

var p5 = new Promise(function (resolve, reject) {
    setTimeout(function() { throw('test 5.1');}, 1000); //This throws an Uncaught Error Exception
    reject('test 5.2'); //This actually happens
    console.log('test 5.3'); //This happens BEFORE the Promise is rejected because reject() is a callback
});

var p6 = new Promise(function (resolve, reject) {
    reject('test 6.1'); //This actually happens
    setTimeout(function() { throw('test 6.2');}, 1000); //This throws an Uncaught Error Exception
    console.log('test 6.3'); //This happens BEFORE the Promise is rejected because reject() is a callback
});


p1.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test1
});

p2.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test2
});

p3.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test3
});

p4.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test4
});

p5.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test5
});

p6.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test6
});


매우 흥미로운 관찰은 사용 throw하면 먼저 reject핸들러 가 처리 error하고 거부 핸들러가 제자리에 없으면 핸들러가 처리한다는 것 입니다.

거부 처리기 블록 사용

var allowed = false;
var p1 = new Promise(
function(resolve, reject) {
  if (allowed)
    resolve('Success');
  else
//         reject('Not allowed');
    throw new Error('I threw an error')
})

p1.then(function(fulfilled) {
console.log('Inside resolve handler, resolved value: ' + fulfilled);
}, function(rejected) {
console.log('Inside reject handler, rejected value: ' + rejected);
}).catch(function(error) {
console.log('Inside error handler, error value: ' + error);
})

거부 처리기 블록 없음

var allowed = false;
var p1 = new Promise(
function(resolve, reject) {
  if (allowed)
    resolve('Success');
  else
//         reject('Not allowed');
    throw new Error('I threw an error')
})

p1.then(function(fulfilled) {
console.log('Inside resolve handler, resolved value: ' + fulfilled);
}).catch(function(error) {
console.log('Inside error handler, error value: ' + error);
})

Additionally, the catch block will be able catch any error thrown inside the resolve handler.

var allowed = true;
var p1 = new Promise(
function(resolve, reject) {
  if (allowed)
    resolve('Success');
  else
//         reject('Not allowed');
    throw new Error('I threw an error')
})

p1.then(function(fulfilled) {
console.log('Inside resolve handler, resolved value: ' + fulfilled);
throw new Error('Error created inside resolve handler block');
}).catch(function(error) {
console.log('Inside error handler, error value: ' + error);
})

It looks like it's best to use throw, unless you can't if you are running some async task, you will have to pass the reject callback down to the async function. But there's a work around, that is is to promisifying your async function. More on https://stackoverflow.com/a/33446005

ReferenceURL : https://stackoverflow.com/questions/28703241/promise-constructor-with-reject-call-vs-throwing-error

반응형