Node.js의 약속 이해


147

내가 이해 한 것에서 비동기 코드를 호출하는 세 가지 방법이 있습니다.

  1. 예를 들어 이벤트 request.on("event", callback);
  2. 콜백, 예 : fs.open(path, flags, mode, callback);
  3. 약속

노드 약속 라이브러리를 찾았 지만 얻지 못했습니다.

누군가 어떤 약속이 무엇인지, 왜 그것을 사용해야하는지 설명 할 수 있습니까?

또한 왜 Node.js에서 제거 되었습니까?


이 기사 는 오히려 잘 설명합니다. 이 Node.js를에서 구현 가능한 올 때, 한 번 봐 걸릴 선물을
숀 킨제이에게

다음은 제 자신의 약속 클래스를 만드는 데 사용한 훌륭한 시리즈입니다 . 프레임 워크 만들기 : 약속 jQuery 지연에 대한 비디오는 다음과 같습니다. blog.bigbinary.com/2011/09/03/jquery-deferred.html
Tom Winter

답변:


91

node.js의 약속은 약간의 작업을 약속 한 다음 타임 아웃 처리뿐만 아니라 성공 및 실패를 위해 실행될 별도의 콜백을 가졌습니다. node.js에서 약속을 생각하는 또 다른 방법은 성공과 오류라는 두 가지 이벤트 만 발생시킬 수있는 이미 터라는 것입니다.

약속에 대한 멋진 점은 약속 체인을 종속성 체인으로 결합 할 수 있다는 것입니다 (약속 A Promise B가 완료된 ).

코어 node.js에서 그것들을 제거함으로써 코어 위에 놓을 수있는 다양한 약속의 구현으로 모듈을 구축 할 수있는 가능성을 만들었습니다. 이것들 중 일부는 노드 약속미래 입니다.


10
@ weng 아니에요.
Ivo Wetzel

98

이 질문에는 여전히 (내 것과 같은) 많은 견해가 있으므로 다음과 같이 지적하고 싶습니다.

  1. 노드 약속 은 나에게 다소 죽은 것처럼 보이며 (마지막 커밋은 약 1 년 전) 테스트는 거의 포함되지 않았습니다.
  2. 선물 매우 나에게 비 대한 모습을 모듈 심하게 설명되어 있습니다 (그리고 나는 명명 규칙은 단지 나쁜 생각)
  3. 가장 좋은 방법 은 활발하고 잘 문서화 된 q 프레임 워크 인 것 같습니다 .

9
github.com/medikoo/deferred 도 확인하십시오 .Q 는 첫 번째 중 하나이며 이후에 나온 많은 구현에 영감을 주었지만 불행히도 일부 부분에서는 너무 느리고 너무 "이론적"이며 일부는 잘 작동하지 않습니다. 실제 시나리오
Mariusz Nowak


23
2014 업데이트- 블루 버드 가 가장 빠르며 오늘날 최고의 디버깅 기능을 갖춘 업데이트입니다.
Benjamin Gruenbaum

19

약속은 말하자면 "최종"작업의 결과를 나타내는 "사물"입니다. 여기서 주목해야 할 점은 어떤 일이 발생 했을 때 의 세부 사항을 추상화하고 그 일이 일어난 발생해야 할 일에 집중할 수 있다는 것입니다. 이로 인해 콜백 내부의 콜백 내부에 콜백이있는 대신 코드가 다음과 같이 깨끗하고 유지 관리 가능한 코드가 생성됩니다.

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

약속의 사양은 약속의

then

메소드는 주어진 successHandler 또는 failureHandler 콜백이 완료 될 때 충족되는 새로운 약속을 리턴해야합니다. 즉, 수행해야하는 비동기 작업 세트가 있고 콜백을 사용한 것처럼 작업 순서가 보장되도록 약속을 묶을 수 있습니다. 따라서 콜백 내부의 콜백 내부에 콜백을 전달하는 대신 체인 된 약속이있는 코드는 다음과 같습니다.

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

약속에 대한 자세한 내용과 그 약속이 왜 멋진 지 확인하려면 Domenic의 블로그를 확인 하십시오 . http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/


12

PouchDB 의 저자의 약속에 관한 이 새로운 튜토리얼 은 아마도 내가 본 것 중에 최고입니다. 그것은 올바른 사용법 패턴을 보여주는 고전적인 신인 실수를 현명하게 다루며 심지어 다른 자습서에서도 여전히 일반적으로 사용되는 몇 가지 안티 패턴을 보여줍니다!

즐겨!

추신 : 나는이 질문의 다른 부분에 대해서는 다른 사람들이 잘 다루었으므로 대답하지 않았습니다.


이것에 대한 나의 유일한 사과는 당신이 고급 실수 # 4의 끝에서 유머를 읽도록 강요하는 것입니다.
Tony O'Hagan 8:25에

실제로, 반 패턴이라고 주장하는 튜토리얼의 코드는 루프와 조건에 대한 중첩이 필요하며 제안한대로 쉽게 전개 할 수 없습니다.
Bergi

고급 실수 # 4 는 훨씬 더 많은 다른 접근 방식을 사용하여 해결할 수도 있습니다 . .then () 체인에서 이전 약속 결과에 어떻게 액세스합니까?를 참조하십시오. ( 그들이 제안 하는 폐쇄 패턴 은별로 인기가없는 것으로 보입니다).
Bergi

이 링크 전용 답변이 더 나은 의견이라고 생각합니다. 여기에 적어도 기사의 요점을 답에 넣으십시오.
Bergi

7

Mike Taulty 에는 일련의 비디오가 있습니다. WinJS Promise 라이브러리의 작동 방식을 설명하는 있습니다.

이 비디오는 매우 유익한 정보이며 Mike는 잘 선택된 몇 가지 코드 예제를 통해 Promise API의 성능을 보여줍니다.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

예외를 처리하는 방법에 대한 처리가 특히 좋습니다.

WinJs 참조에도 불구하고 Promise API는 많은 구현에서 광범위하게 유사하기 때문에 일반적인 관심 비디오 시리즈입니다.

RSVP 는 Promise / A + 테스트 스위트를 통과하는 경량 Promise 구현입니다. WinJS 인터페이스와 스타일이 유사하기 때문에 API를 매우 좋아합니다.

2014 년 4 월 업데이트

또한 WinJS 라이브러리 는 이제 오픈 소스 입니다.


1
+1. 이 차종은 나에게 감지 것을 내가 본 최초의 예입니다 사용이 직관적이다. 어떻게 든 내 머리는 모든 구문 분석 할 수 없습니다 deferredsresolvedeferred.promise.then와의 사전 정의 promiseActions인기 Q 라이브러리 문서입니다. Node.js에 대해 이것을 간단하게 알고 있습니까?
Redsandro

1
@noel 위의 링크를 공유해 주셔서 감사합니다. 약속에 대한 훌륭한 입문 시리즈이며, 전반적인 접근 방식 / 주제가 보편적이므로 WinJS 사양은 관련이 없다는 데 동의합니다.
arcseldon

좋은 예입니다. 또한 나는 죽은 첫 링크를 수정했다
stonedauwg

5

약속의 또 다른 장점은 오류 처리 및 예외 발생 및 포착이 콜백으로 처리하는 것보다 훨씬 낫다는 것입니다.

블루 버드 라이브러리를 구현 약속하고 당신에게 좋은 긴 스택 추적을 제공은 매우 빠르고, 그리고 캐치되지 않는 오류에 대한 경고합니다. http://bluebirdjs.com/docs/benchmarks.html 에 따르면 다른 약속 라이브러리보다 더 빠르고 더 적은 메모리를 사용합니다.


4

약속은 정확히 무엇입니까?

약속은 단순히 비동기 작업의 결과를 나타내는 객체입니다. 약속은 다음 3 가지 상태 중 하나 일 수 있습니다.

보류 중 :: 이것이 초기 상태이므로 약속이 이행되거나 거부되지 않습니다.

성취 됨 : 이것은 약속이 이행되었음을 의미하며, 약속으로 표현 된 가치가 사용될 준비가되었음을 의미합니다.

거부 됨 :: 작업이 실패 했으므로 약속을 이행 할 수 없습니다. 주 외에도 우리가 정말로 이해해야 할 약속과 관련된 세 가지 중요한 실체가 있습니다

  1. executor function :: executor 함수는 수행해야 할 비동기 작업을 정의하고 그 결과가 약속으로 표시됩니다. promise 객체가 초기화 되 자마자 실행을 시작합니다.

  2. resolve :: resolve는 executor 함수에 전달되는 매개 변수이며 executor가 성공적으로 실행되면 결과를 전달하는 것입니다.

  3. reject :: reject는 executor 함수에 전달 된 또 다른 매개 변수이며 executor 함수가 실패 할 때 사용됩니다. 실패 이유는 거부로 전달 될 수 있습니다.

따라서 약속 객체를 만들 때마다 Executor, Resolve 및 Reject를 제공해야합니다.

참조 :: 약속


0

나는 또한 최근 node.js에서 약속을 조사했습니다. 현재까지 when.js는 속도와 자원 사용으로 인해 이동하는 방법,하지만에 대한 설명서 것으로 보인다 q.js 이해 나에게 많은 것을 주었다. 따라서 when.js와 q.js 문서를 사용하여 주제를 이해하십시오.

github 의 q.js readme에서 :

함수가 값을 반환하지 않거나 차단하지 않고 예외를 throw하면 대신 약속을 반환 할 수 있습니다. 약속은 반환 값 또는 함수가 결국 제공 할 수있는 예외를 나타내는 객체입니다. 약속은 원격 개체의 대기 시간을 극복하기위한 프록시로 사용될 수도 있습니다.


0

약속 개체는 비동기 작업의 완료 또는 실패를 나타냅니다.

따라서 약속을 이행하려면 두 부분이 필요합니다.

1. 약속 만들기 :

promise 생성자는 2 개의 매개 변수 해결 및 거부가있는 실행 프로그램이라는 함수를 수락합니다.

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2. 취급 약속 :

Promise 객체에는 promise 객체를 처리하는 3 가지 방법이 있습니다.

1. Promise.prototype.catch (onRejected)

2. Promise.prototype.then (전체 파일)

3. Promise.prototype.finally (onFullfiled, onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.