[javascript] JavaScript에서 Deferred, Promise 및 Future의 차이점은 무엇입니까?

연기, 약속 및 미래의 차이점은 무엇입니까?
이 세 가지 모두에 대해 일반적으로 승인 된 이론이 있습니까?



답변

OP의 질문에 대답하려고 시도한 방법에 대한 혐오감을 분명히 나타냅니다. 문자 그대로의 대답은 약속은 다른 객체와 공유되는 것이며 지연된 것은 비공개로 유지해야한다는 것입니다. 기본적으로 지연된 (일반적으로 약속을 연장하는) 지연 자체가 해결 될 수 있지만 약속은 그렇지 않을 수 있습니다.

축소에 관심이 있다면 Promises / A + 를 조사하십시오 .


내가 아는 한, 가장 중요한 목적은 표준화 된 인터페이스를 통해 선명도를 높이고 결합을 느슨하게하는 것입니다. @ jfriend00의 추천 글 을 참조하십시오 :

약속을 사용하여 밀접하게 연결된 인터페이스로 이어질 수있는 콜백을 함수에 직접 전달하는 대신 약속을 사용하면 동기식 또는 비동기 코드에 대한 우려를 분리 할 수 ​​있습니다.

개인적으로 비동기 요청에 의해 채워지는 템플릿, 종속성 네트워크가있는 스크립트로드 및 비 차단 방식으로 데이터를 형성하기 위해 사용자 피드백을 제공하는 등의 작업을 처리 할 때 특히 유용한 지연이 발견되었습니다.

실제로 JS 모드에서 CodeMirror를 비동기 적으로로드 한 후 무언가를 수행하는 순수한 콜백 형식을 비교하십시오 (죄송합니다. 한동안 jQuery를 사용하지 않았습니다 ).

/* assume getScript has signature like: function (path, callback, context)
   and listens to onload && onreadystatechange */
$(function () {
   getScript('path/to/CodeMirror', getJSMode);

   // onreadystate is not reliable for callback args.
   function getJSMode() {
       getScript('path/to/CodeMirror/mode/javascript/javascript.js',
           ourAwesomeScript);
   };

   function ourAwesomeScript() {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   };
});

약속 된 버전 (다시 말해서, jQuery에 대해서는 최신 상태가 아닙니다) :

/* Assume getScript returns a promise object */
$(function () {
   $.when(
       getScript('path/to/CodeMirror'),
       getScript('path/to/CodeMirror/mode/javascript/javascript.js')
   ).then(function () {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   });
});

세미 의사 코드에 대한 사과이지만 핵심 아이디어가 다소 명확 해지기를 바랍니다. 기본적으로 표준화 된 약속을 반환하면 약속을 전달할 수 있으므로보다 명확한 그룹화가 가능합니다.


답변

선택한 답변을 포함하여이 대답은, 개념적으로 약속을 도입,하지만 정확히 차이 (거기를 구현하는 라이브러리를 사용할 때 발생하는 용어 무엇인지 구체적인 부족을 위해 좋은
입니다 중요한 차이점).

여전히 진화하는 spec 이므로 답은 현재 wikipedia 와 같은 참조 와 jQuery 와 같은 구현을 모두 조사하려고 시도한 결과입니다 .

  • Deferred : 널리 알려진 참고 문헌, 1 2 3 4에 설명되어

    있지는 않지만 구현에서 약속 해결의 중재자 (구현 및 ) 로 일반적으로 사용됩니다 .
    5 6 7




    resolvereject



    때로는 deferreds는 (이행 약속도 있습니다 then),
    (5) (6)
    더 순수한으로 볼 수있어 다른 배 이연 해상도의 수 및 액세스에 대한 사용자 사용에 대한 약속을 강요 한 것으로는 .
    7


    then

  • 약속 : 논의중인 전략에 대한 가장 포괄적 인 단어.

    우리가 추상화하고자하는 목표 함수의 결과를 저장하고, then다른 목표 함수를 받아들이고 새로운 약속을 반환하는 함수를 노출시키는 프록시 객체 .
    2

    CommonJS의 예 :

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44

     

    책임 해결에 속하는 사람을 지정하지는 않았지만 항상 널리 알려진 참조에 설명되어 있습니다.
    1 2 3 4




    항상 널리 사용되는 구현에 존재하며 해결 능력이 주어지지 않습니다.
    5 6 7



  • 미래 : 일부 인기있는 참고 문헌 1
    과 적어도 하나의 인기있는 구현에서
    발견 된 겉보기가 더 이상 사용되지 않는 용어
    8
    , 그러나 ‘약속’ 3 이라는 용어에 대한 선호도가 토론에서 단계적으로 폐지 된 것으로 보이며

    항상 주제에 대한 대중적인 소개에서 언급되지는 않습니다.
    9







    그러나 최소한 하나의 라이브러리는 일반적으로 then기능을 제공하지 않으면 서 동기화 및 오류 처리를 추상화하기 위해 일반적으로이 용어를 사용합니다 .
    10
    ‘약속’이라는 용어를 피하는 것이 의도적 인 것인지는 확실하지 않지만 약속은 ‘Thenables’를 중심으로하기 때문에 좋은 선택 일 것입니다.
    2



참고 문헌

  1. 약속과 선물에 관한 위키 백과
  2. 약속 / A + 사양
  3. 약속에 대한 DOM 표준
  4. DOM 표준 약속 사양 WIP
  5. DOJO 툴킷 연기
  6. jQuery 연기
  7. 미래 JS
  8. 약속에 관한 기능적 JavaScript 섹션
  9. AngularJS 통합 테스트의 미래

잠재적으로 혼란스러운 것들


답변

실제로 나를 위해 클릭 한 것은 Domenic Denicola의 프레젠테이션 이었습니다.

A의 github의의 요점 , 그는 대부분의 같은 설명 나는, 아주 간결입니다했다 :

약속의 요점은 비동기 세계에서 기능 구성과 오류 버블 링을 다시 제공하는 것입니다.

다시 말해 약속은 비동기식 코드를 동기식 처럼 작성하기가 쉬운 비동기식 코드를 작성할 수있는 방법입니다 .

약속과 함께이 예를 고려하십시오.

getTweetsFor("domenic") // promise-returning async function
    .then(function (tweets) {
        var shortUrls = parseTweetsForUrls(tweets);
        var mostRecentShortUrl = shortUrls[0];
        return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
    })
    .then(doHttpRequest) // promise-returning async function
    .then(
        function (responseBody) {
            console.log("Most recent link text:", responseBody);
        },
        function (error) {
            console.error("Error with the twitterverse:", error);
        }
    );

이 동기 코드를 작성하는 것처럼 작동합니다.

try {
    var tweets = getTweetsFor("domenic"); // blocking
    var shortUrls = parseTweetsForUrls(tweets);
    var mostRecentShortUrl = shortUrls[0];
    var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
    console.log("Most recent link text:", responseBody);
} catch (error) {
    console.error("Error with the twitterverse: ", error);
}

(여전히 복잡하게 들리면 프레젠테이션을보십시오!)

연기에 관해서는, 그것은 방법 .resolve()또는 .reject()약속입니다. 에서 약속 / B의 스펙, 그것은이라고합니다 .defer(). jQuery에서는 $.Deferred()입니다.

내가 아는 한 jQuery 1.8.2에서 jQuery의 Promise 구현이 중단되었습니다 (요점 참조).
아마도 Promises / A thenables 구현 하지만 전체 “비동기 시도 / 캐치”기능이 작동하지 않는다는 점에서 올바른 오류 처리를 얻지 못합니다. 비동기 코드와 함께 “try / catch”를 사용하는 것이 정말 멋지므로 유감입니다.

약속을 사용하려면 (자신의 코드로 시도해야합니다!) Kris Kowal의 Q를 사용하십시오 . jQuery 버전은 더 깨끗한 jQuery 코드를 작성하기위한 콜백 애그리 게이터 일뿐입니다.

미래에 관해서는, 나는 어떤 API에서도 그것을 보지 못했습니다.

편집 : 약속에 Domenic Denicola의 유튜브 이야기 에서 @Farm 아래의 코멘트.

비디오 에서 Michael Jackson (예, Michael Jackson ) 의 인용문 :

나는 당신이이 문구를 당신의 마음 속에 태우 길 원합니다.
약속은 비동기적인 가치 입니다.

이것은 훌륭한 설명입니다. 약속은 미래의 변수와 같습니다-어떤 시점에서 존재하거나 일어날 일에 대한 일류 참조.


답변

약속은 약속이 만들어 질 때 값에 대한 프록시가 반드시 알려진 나타냅니다. 핸들러를 비동기 조치의 최종 성공 값 또는 실패 이유에 연관시킬 수 있습니다. 이를 통해 비동기 메소드는 동기 메소드와 같은 값을 리턴 할 수 있습니다. 최종 값 대신 비동기 메소드는 미래의 어느 시점에서 값을 가질 가능성을 리턴합니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

deferred.promise()메소드는 비동기 함수가 다른 코드가 내부 요청의 진행 또는 상태를 방해하지 않도록합니다. Promise는 추가 처리기를 연결하거나 상태 (결정 , 완료, 실패, 항상, 파이프, 진행 상태, 상태 및 약속 )를 결정하는 데 필요한 지연된 메소드 만 노출 하지만 상태를 변경하는 것은 아닙니다 ( resolve, reject, notify, resolveWith, rejectWith 및 notifyWith ).

대상이 제공되면 deferred.promise()메소드를 첨부 한 다음 새 오브젝트를 작성하지 않고이 오브젝트를 리턴합니다. 이미 존재하는 개체에 Promise 동작을 연결하는 데 유용 할 수 있습니다.

지연을 작성하는 경우 특정 시점에서 해결되거나 거부 될 수 있도록 지연에 대한 참조를 유지하십시오. 다른 코드가 콜백을 등록하거나 현재 상태를 검사 할 수 있도록 deferred.promise ()를 통해 Promise 객체 만 반환합니다.

간단히 말해 약속 은 아직 연기 되지 않은 작업을 나타내는 것으로 아직 알려지지 않은 값을 나타낼 수 있습니다 .


여기에 이미지 설명을 입력하십시오


답변

  • A promise는 아직 알려지지 않은 값을 나타냅니다
  • A deferred는 아직 끝나지 않은 작품을 나타냅니다

약속은 초기에 알려지지 않은 결과에 대한 자리 표시 자이며 지연은 값을 산출하는 계산을 나타냅니다.

참고


답변