2016-12-13 3 views
1

Bluebird의 finally에 대한 문서를 볼 수 있지만 차이점은 then 대 아직도 이해가되지 않습니다.그 때와 마지막으로 약속의 차이점은 무엇입니까?

명확하게 : catch 뒤에 then이 왜 호출되는지 정확히 알고 있습니다. I 은 캐치 후에을 호출하려고합니다. 그것이 의도입니다. 제 질문은 : 이 약속 상태에 관계없이 항상 실행될 코드 인 경우 thenfinally의 차이점은 무엇입니까? 해결 된 약속

  1. .then(...).catch(...).then(...) :

    var Promise = require("bluebird"); 
    
    function test1() { 
        console.log("RESOLVE + THEN + CATCH + THEN"); 
        return new Promise((resolve, reject) => resolve()) 
         .then(() => console.log("then")) 
         .catch(err => console.log("error:", err.message)) 
         .then(() => console.log("end")); 
    } 
    
    function test2() { 
        console.log("REJECT + THEN + CATCH + THEN"); 
        return new Promise((resolve, reject) => reject(new Error("rejected"))) 
         .then(() => console.log("then")) 
         .catch(err => console.log("error:", err.message)) 
         .then(() => console.log("end")); 
    } 
    
    function test3() { 
        console.log("RESOLVE + THEN + CATCH + FINALLY"); 
        return new Promise((resolve, reject) => resolve()) 
         .then(() => console.log("then")) 
         .catch(err => console.log("error:", err.message)) 
         .finally(() => console.log("end")); 
    } 
    
    function test4() { 
        console.log("REJECT + THEN + CATCH + FINALLY"); 
        return new Promise((resolve, reject) => reject(new Error("rejected"))) 
         .then(() => console.log("then")) 
         .catch(err => console.log("error:", err.message)) 
         .finally(() => console.log("end")); 
    } 
    
    // run tests "sequentially" so console output doesn't get blended 
    setTimeout(test1, 500); 
    setTimeout(test2, 1000); 
    setTimeout(test3, 1500); 
    setTimeout(test4, 2000); 
    

    이 네 개의 케이스를 테스트합니다

    나는이 테스트를 만들었습니다.
  2. .then(...).catch(...).then(...) 약속이 거부되었습니다.
  3. .then(...).catch(...).finally(...) 해결 된 약속이 있습니다.
  4. .then(...).catch(...).finally(...) 약속이 거부되었습니다. I 참조

결과는 1 개 + 2 + 3과 동일하게 행동한다 (4)의 경우이다 : 의도 한대로 마지막 비트 (thenfinally 또는 테스트)에 따라, 이전에 관계없이 일어나는 실행하지 않는다. 나는 comment on this other question I asked 보았 기 때문에 이제

RESOLVE + THEN + CATCH + THEN 
then 
end 
REJECT + THEN + CATCH + THEN 
error: rejected 
end 
RESOLVE + THEN + CATCH + FINALLY 
then 
end 
REJECT + THEN + CATCH + FINALLY 
error: rejected 
end 

, 내가 부탁 해요 이유는 다음과 같습니다 : 그 프로그램의 출력은 당신의 약속을 지원하는 경우

확실하지,하지만 당신은 마지막 .then을 변경해야합니다 .finally으로 변경하여 busy이 항상 지워집니다. then이 충분처럼 내 매우 제한된 then의 지식, 위의 테스트에서

, 그것은 보인다. 그러나 그 의견을 말한 후에 나는 "finally"코드를 실행하기 위해 then을 사용하는 자신과 안전에 대해 질문하고 있습니다.

제 질문은 thenfinally의 차이점은 무엇입니까? 그들은 처럼처럼 보이지만, 언제 then 대신 finally을 사용해야합니까?

+0

귀하의 질문은 왜 종결되는 것 같습니까? 그렇다면 귀하의 거절 된 약속에 전화를 걸겠습니까? .catch 문서를 읽으면 대답 할 수 있습니다. –

+0

@KevinB 아니, 전혀. 나는 왜 '다음'이 '캐치'후에 호출되는지 정확히 알 수 있습니다. 나는 * 캐치 후에 호출하도록 * 요청합니다. 나는 묻는다 : 만약 약속 상태에 관계없이 * 코드가 항상 실행되기를 원한다면,'then'과'finally'의 차이는 무엇인가? –

+1

당신이 항상 거부 된 약속을 포착한다면, 오직 당신이 약속을 해결했을 뿐이며, 물론 약간의 차이가 있습니다 ... 나는 당신의 질문의 요점을 놓치고 있습니까? 이 모든 것은 명백해 보인다. –

답변

3

첫 번째 차이점 : 때로는 발생하는 곳에서 오류를 잡기를 원하지 않지만이 기능을 사용하는 코드에서는 오류를 잡아 내지 않으려 고합니다. 이 경우 then()finally()을 대체 할 수 없습니다.

때로는 오류가 있었는지 여부에 관계없이 무언가를 정리해야합니다 (참조를 무효로하고 제한 시간을 지우는 등 ...). 그것은 finally()을 사용하는 곳입니다.

두 번째 차이점 : catch()에 전달하는 함수도 throw 될 수 있습니다. 그러면 Promise가 거부되어 다음 then()이 호출되지 않습니다.

(캐치 여전히 오류에서 실행하기 전에 그래서 결국, 몰랐어)

그래, 그 finally()의 요점

. 해결 된 가치를 변경하지 않고 어떤 상황에서도 실행됩니다.

약/try {} finally {}에 대해/google을 조금 읽고 싶을 수도 있습니다.

0

KevinB의 채팅과 많은 도움을받은 후, 적어도 하나의 차이점을 발견했습니다. 약속이 거부 이들에

function test5() { 
    console.log("REJECT + THEN + CATCH/THROW + THEN"); 
    return new Promise((resolve, reject) => reject(new Error("rejected"))) 
     .then(() => console.log("then")) 
     .catch(function(err) { throw new Error("error in catch"); }) 
     .then(() => console.log("end")); 
} 

function test6() { 
    console.log("REJECT + THEN + CATCH/THROW + FINALLY"); 
    return new Promise((resolve, reject) => reject(new Error("rejected"))) 
     .then(() => console.log("then")) 
     .catch(function(err) { throw new Error("error in catch"); }) 
     .finally(() => console.log("end")); 
} 

,하지만 오류가 catch에서 발생합니다 : 다음 두 가지 새로운 테스트를 고려하십시오.

약속은 두 경우 모두 궁극적으로 거부되지만, finally의 경우 finally이 아직 실행 중이면 then은 실행되지 않습니다.

그래서 입니다. 그들은 거의인데, 유일한 예외는 catch 핸들러에서 finally 핸들러가 실행될 때 then이 실행되지 않습니다.

이는 내가 인용 한 주석의 장점을 나타냅니다. 내 오류 처리기에서 다른 오류가 발생하면 then은 정리를 보장하지 않지만 finally은 오류를 처리합니다. 그게 내가 놓친 사건이야.

+2

또한'.finally'는 약속을 위해 결정된 값에 영향을 미치지 않지만'.then'은 그렇게됩니다. – Matt

+0

@Matt, 함수가'undefined'를 반환하면 안됩니다. 하지만 당신 말이 맞습니다. 'finally()'는 해결 된 값이 변경되지 않도록합니다. – Thomas

+0

@ 토마스 귀하의'정의되지 않은'주의 사항을 이해하지 못해 죄송합니다. 어디에서나'undefined '를 반환하면 효과가 보이지 않는다는 것을 의미합니까? – Matt

3

.then.finally은 동일하지 않습니다.

.then은 주요 약속 프리미티브입니다. 이는 Promises/A+ spec에서 철저하게 정의 된 것이며 모든 약속 라이브러리에서이를 구현합니다.

Bluebird .finally 처리기는 "약속의 운명과 상관없이"호출됩니다. 따라서 처리되지 않은 예외가 여전히 .finally을 트리거합니다.

new Promise((resolve, reject) => reject(false)) 
    .finally(a => console.log('finally', a)) 
// finally undefined 
// Unhandled rejection false 

new Promise((resolve, reject) => reject(false)) 
    .then(a => console.log('then', a)) 
// Unhandled rejection false 

.finally은 약속의 해결 된 값을 변경하지 않으며 약속 체인의 결과를받지 않습니다. 테스트는 모든 오류를 잡아에만 흐름 제어에 대한 약속을 사용으로

new Promise((resolve, reject) => reject(false)) 
    .catch(e => { 
    console.log(e) 
    return 2 
    }) 
    .finally(a => { 
    console.log('finally', a) 
    return 1 
    }) 
    .then(res => console.log('res', res)) 
// finally undefined 
// res 2 

방법은되는 값에 의존하지, 테스트의 경우와 유사 해결/약속 체인을 따라 거부했다.

+1

덧붙여 말하자면, 새로운 약속 (resolve => resolve (true) 만약 누군가 다른 사람이이 글을 읽었 으면, 이제 나는이 개념들을 알아 냈다. 나는 다른 것들을 발견했다. 그리고 .tap()은 하나이다 :'tap'은'then'과'finally' 사이의 중간 정도입니다. ':'then'과 마찬가지로 거절시 호출되지 않지만'finally'처럼 결과를 변경하지 않으므로 이전 결과는 그 위에 건너 뜁니다. 산뜻한. –