약속 상태 손실, 받아들이지 않음

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이 되돌아온 약속은 원래의 약속이 실패할 때 성공적으로 실현될 것이다.)따라서 onRejectedrejected으로 되돌려주겠다는 약속은 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을 준수하겠다는 약속이 포함되어 있습니다.
가령 onRejectedmap은 매우 비슷하다. 그들은 모두 약속이 완성될 때 리셋을 실행하고 결과를 포함하는 새로운 약속을 되돌린다.그것들의 유일한 차이점은 성공할 때 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 안녕, 바울아,
나는 방금 chainmap 방법의 실현을 더욱 자세하게 이해했다.거절당한 약속에 대해

토론 #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의 기본 행위는 이미 이루어진 약속을 되돌리는 것이다.chainErroronRejected은 같은 목적(즉, 거절당한 약속을 이행한 약속으로 전환)을 가지지만 첫 번째 상황에서 리셋 함수는 반드시 새로운(거절당하거나 이행된) 약속을 되돌려야 하고 두 번째 상황에서 이미 이행한 승낙치를 되돌려야 한다.

토론 #9

Hi@rbelouin,
저는 Pacta에 다시 한 번 노력하여 Promises에 완전하고 ECMAScript 2015과 호환되는 API(당신은 separate branch에서 진전을 볼 수 있습니다)를 제공합니다. 저는 mapErrorchainError을 다시 생각하고 있습니다.
나는 mapError에 찬성하지 않는다. 왜냐하면 그것은 완전히 onRejected에 따라 실현할 수 있기 때문이다.
Promise.prototype.mapError = function (f) {
    return this.onRejected(function (reason) {
        throw f(reason);
    });
};
이는 기초대수인 API(즉 Fantasy Land)의 표면적을 maponRejected(일정한 대칭성을 가진)으로 줄일 것이다.
잃어버린 API로 약속을 되돌려 주는 함수를 지원하려면 chainError이 필요하며, 이 함수들은 거부될 수밖에 없다는 것이다.나는 그 별명을 chainRejected으로 하여 map, onRejectedchain, 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

니스:)

좋은 웹페이지 즐겨찾기