약속 상태 손실, 받아들이지 않음
9256 단어 pacta
묘사
은pacta자술파일의 정의에 따르면onRejected는 "약속 #과 동일하지만 약속이 해결되지 않고 거부될 때만 실행됩니다."그래서 나는 왜 아래의 테스트가 비등가인지 모르겠다.
/* test 1 */
var p = new Promise();
var pp = p.map(x => x + 1).map(x => x * 2).map(console.log);
p.resolve(0);
// prints "2"
/* test 2 */
var p = new Promise();
var pp = p.onRejected(x => x + 1).onRejected(x => x * 2).onRejected(console.log);
p.reject(0);
// does not print anything
실제로 onRejected는 다음과 같이 가정된 Promise#forEach와 완전히 같아 보입니다./* test 3 */
var p = new Promise();
var pp = p.onRejected(console.log);
p.reject(0);
// prints "0"
하지만var p = new Promise(42);
var pp = p.onRejected(x => x);
p.value == pp.value; // false because pp.value is not defined
var p = new Promise(); p.reject(42);
var pp = p.onRejected(x => x);
p.reason == pp.reason; // false because pp.reason is not defined
나는 원래 그것이 연결될 수 있다고 생각했지만, 사실은 그렇지 않은 것 같다.토론 #1
안녕, 루돌프,문제는
onRejected
이 새로운 약속인 fulfilled
으로 돌아왔지만 거절당했다(rejected
이 아니다).그래서 너의 예를 들면:var p = new Promise();
p.reject(42);
var pp = p.onRejected(function (x) { return x; });
p.state() // 'rejected'
pp.state() // 'fulfilled'
p.reason === pp.value // because p's rejection is pp's fulfilment
따라서 링크의 경우 onRejected
, 그리고 map
을 사용할 수 있습니다.var p = new Promise();
var pp = p.onRejected(function (x) { return x + 1; }).map(function (x) { return x * 2; }).map(console.log);
p.reject(0);
// prints "2"
나는 이 점이 특별히 뚜렷하지 않다는 것에 동의한다. (즉 onRejected
이 되돌아온 약속은 원래의 약속이 실패할 때 성공적으로 실현될 것이다.)따라서 onRejected
을 rejected
으로 되돌려주겠다는 약속은 fulfilled
(토론 #2
이 아님)이고 최초의 예시로 일할 수 있습니까?rejected
안녕, 바울아,답변 감사합니다.만약 돌아오는 약속이
토론 #셋
이라면, 나는 그것이 작용할 것이라고 생각한다.onFulfilled
저는 Pacta를 최신 Promises/A+ specification에 부합하도록 업그레이드하는 것을 연구하고 있습니다. 여기서 존재할 수 있는 문제는 2.2.7.1. If either onRejected
or x
returns a value [[Resolve]](promise2, x)
, run the Promise Resolution Procedure onRejected
점입니다. 즉, onRejected
의 반환값은 최종 약속을 실현하는 데 사용됩니다.수시로 알려 드리지만,
onRejected
에서 이상을 던질 때만 토론 #4
의 여러 호출을 연결해야 유효할 수 있습니다. 성공적인 반환은 사실상 실패를 성공으로 바꿀 수 있습니다.e, g. 이런 용례:
var p = new Promise();
p.onRejected(function (reason) {
if (reason instanceof TypeError) {
throw new Error('No recovery!');
} else {
return 'Some graceful recovery.';
}
});
p.reject(new TypeError('Fatal error!'));
map
방금 발표된 Pacta 0.4.0에는 API 변경 사항이 포함되어 있으며 이를 더욱 잘 지원하기 위해/A+2.0을 준수하겠다는 약속이 포함되어 있습니다.가령
onRejected
과 map
은 매우 비슷하다. 그들은 모두 약속이 완성될 때 리셋을 실행하고 결과를 포함하는 새로운 약속을 되돌린다.그것들의 유일한 차이점은 성공할 때 onRejected
을 사용하고 실패할 때 onRejected
을 사용하는 것이다.그들이 모두 새로운 약속에 보답할 때 실패를 성공으로 바꾸고 성공을 실패로 바꿀 수도 있다.var p = new Promise();
p.map(function (x) {
throw 'Turn this success into a failure';
});
p.onRejected(function (reason) {
return 'Turn this failure into a success';
});
만약 rejected
aways가 토론 #5
의 약속을 회답했다면 쉽게 회복할 수 없었을 것이다.예를 들어 다른 단계로 URL을 가져오는 것을 상상해 보세요. 요청이 실패하면 다시 시도하거나 완전히 다른 URL로 변경할 수 있는 메커니즘이 있습니다. 이것은 매우 유용할 것입니다.나는 Who Scala deals with failures in Futures and Promises에서 많은 정보를 얻었지만 피드백을 받아들이고 싶다.이게 의미가 있나요?
onRejected
에서 약속/A+규범을 읽은 후에 저는 당신이 mapRejected
의 행위를 바꾸어서는 안 된다고 생각합니다.그러나 나는 당신들이
map
(임의로 명명) 을 추가하는 것을 장려합니다. 그것은 완전한 약속으로 돌아가지 않을 것입니다.사실 나는
mapRejected
또는 value
이 새로운 약속으로 돌아오는 것을 원하지 않는다. 나는 그들이 주어질 수 있는 reason
또는 chain
에 함수를 응용하기를 바랄 뿐이다.당신의 aax 호출에서, 나는 차라리 rejected
등가물을 사용하여 토론 #6
의 약속을 실현하고 싶습니다.다음과 같은 방법으로 쉽게 정의할 수 있습니다.
var fetchText = function(url) {
var p = new Promise();
/* ajax call */
return p;
};
var fetchJSON = function(url) {
return fetchText(verb, url).map(JSON.parse).mapError(JSON.parse);
};
var fetchUser = function(name) {
return fetchJSON("/users/" + name).chainError(function() {
return fetchJSON("/users/default");
});
};
fetchUser("john-cleese").map(console.log).mapError(console.error);
어떻게 생각하세요?map
안녕, 바울아,나는 방금
chain
과 map
방법의 실현을 더욱 자세하게 이해했다.거절당한 약속에 대해 토론 #7
호출은 미정된 약속을 되돌려준다는 충분한 이유가 있는가?var p = new Promise();
p.reject("error");
var a = p.chain(x => x + 1);
console.log(a.state()); // print "pending"
이것은 제가 제안한 새로운 방법입니다. 제가 패키지에서 그것을 실현할 수 있도록 허락해 주시겠습니까? 아니면 개인 약속 라이브러리를 개발하고 싶습니까?-- e and f are error types
-- a and b are success types
map :: Promise e a -> (a -> b) -> Promise e b
chain :: Promise e a -> (a -> Promise e b) -> Promise e b
mapError :: Promise e a -> (e -> f) -> Promise f a
chainError :: Promise e a -> (e -> Promise f a) -> Promise f a
map
나는 이곳의 문제는 onRejected
이 거절을 소홀히 한 것이라고 의심한다(이것은 내가 a
을 추가하기 전에 Fantasy Land의 합법성을 실현했기 때문이다).첫 번째 예에서 나는
rejected
이 즉시 error
reason
이 되기를 희망한다. chain
이 함수 f
을 받아들였기 때문에 이 함수는 약속을 되돌려 주고 원래 약속한 내용에 따라 그것을 운행한다.이것은 당신의 기대에 부합됩니까?var p = new Promise();
p.reject('error');
var a = p.chain(function (x) { return Promise.of(x + 1); });
console.log(a.state()); // print "rejected"
console.log(a.reason); // print "error"
이것은 틀림없이 당신에게 제의한 chainError
에 빈틈을 남길 것입니다(mapError
은 현재의 onRejected
과 다르습니까)?토론 #8
응, 나는 그렇게 생각하지 않는다.mapError
의 목적은 주어진 원인을 다른 원인(예를 들어 줄 텍스트를 JSON 데이터로 해석하는 것)으로 바꾸는 것이고, onRejected
의 기본 행위는 이미 이루어진 약속을 되돌리는 것이다.chainError
과 onRejected
은 같은 목적(즉, 거절당한 약속을 이행한 약속으로 전환)을 가지지만 첫 번째 상황에서 리셋 함수는 반드시 새로운(거절당하거나 이행된) 약속을 되돌려야 하고 두 번째 상황에서 이미 이행한 승낙치를 되돌려야 한다.토론 #9
Hi@rbelouin,저는 Pacta에 다시 한 번 노력하여 Promises에 완전하고 ECMAScript 2015과 호환되는 API(당신은 separate branch에서 진전을 볼 수 있습니다)를 제공합니다. 저는
mapError
과 chainError
을 다시 생각하고 있습니다.나는
mapError
에 찬성하지 않는다. 왜냐하면 그것은 완전히 onRejected
에 따라 실현할 수 있기 때문이다.Promise.prototype.mapError = function (f) {
return this.onRejected(function (reason) {
throw f(reason);
});
};
이는 기초대수인 API(즉 Fantasy Land)의 표면적을 map
과 onRejected
(일정한 대칭성을 가진)으로 줄일 것이다.잃어버린 API로 약속을 되돌려 주는 함수를 지원하려면
chainError
이 필요하며, 이 함수들은 거부될 수밖에 없다는 것이다.나는 그 별명을 chainRejected
으로 하여 map
, onRejected
과 chain
, chainRejected
의 관계를 맺을 수 있다.호환성 때문에 실제로는
mapError
을 라이브러리에 남기지만 문서에서 삭제할 수도 있습니다.당신은 어떤 의견이나 반대 의견이 있습니까?
토론 #10
안녕!질문해 주셔서 감사합니다. 저는 아무런 이의도 없습니다.문서에서 삭제하는 것은 좋은 생각입니다. 만약 사용할 수 있다면,
console.warn()
을 통해 경고를 추가할 수도 있습니다.토론 #11
이렇게 빠른 답변에 감사드립니다. 저도util.deprecate
을 사용할 가능성을 고려하고 있습니다. (비록 브라우저에polyfill을 추가해야 하지만.)토론 #12
@rbelouin 저는 Pacta 0.9를 발표했습니다. 그 중에서 새로운mapError
(현재 문서 기록이 없습니다)은 onRejected
에 따라 실현되었습니다.이렇게 함으로써 나는 마침내 네가 onRejected
을 연결할 때 겪은 문제를 발견했다. 그것은 약속의 성공 상태를 잃게 될 것이다.Promise.resolve(1).onRejected(function () { return 2; }).map(console.log); //=> should be 1
이것도 0.9에 고정되어 있다.토론 #13
니스:)Reference
이 문제에 관하여(약속 상태 손실, 받아들이지 않음), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://github.com/mudge/pacta/issues/4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)