ES6-새 컨텐츠(3) Promise 객체

22895 단어 학습 노트

1. Promise 객체


1. 특징


Promise 객체는 Pending(진행 중), Resolved(완료됨, 일명 Fulfilled) 및 Rejected(실패) 등 세 가지 비동기식 작업을 나타냅니다.일단 상태가 바뀌면 다시 변하지 않고 언제든지 이 결과를 얻을 수 있다.Promise 대상이 있으면 비동기 조작을 동기화 조작의 절차로 표현할 수 있어 겹겹이 끼워 넣은 리셋 함수를 피할 수 있다.

2.기본용법

var promise=new Promise(function(resolve,reject){
	//...
	if(/* */){
		resolve(value);
	}else{
		reject(value);
	}
});
// 
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

resolve: Promise 객체의 상태를 완료되지 않은 상태에서 성공(Pending에서 Resolved)으로 변경하고 비동기 작업이 성공했을 때 호출하며 비동기 작업의 결과를 매개 변수로 전달합니다.Reject: Promise 객체의 상태를 완료되지 않음에서 실패(Pending에서 Rejected)로 변경하고 비동기 작업이 실패할 때 호출하며 비동기 작업이 보고한 오류를 매개 변수로 전달합니다.

3.API


1)then()


이 기능은 Promise 인스턴스에 상태 변경 시 콜백 함수를 추가하는 것입니다.
n 방법은 새로운 Promise 실례를 되돌려줍니다. (원래 그 Promise 실례가 아닙니다.)따라서 체인식 쓰기, 즉then 방법 뒤에 다른then 방법을 사용할 수 있다.예:
getJSON("/post/1.json").then(
  post => getJSON(post.commentURL)
).then(
  comments => console.log("Resolved: ", comments),
  err => console.log("Rejected: ", err)
);

2)catch()


catch 방법은 then (null,rejection) 의 별명으로 오류가 발생했을 때의 리셋 함수를 지정하는 데 사용됩니다.
다음 코드에서:
4
  • getJSON 방법은 Promise 대상을 되돌려줍니다. 이 대상의 상태가 Resolved로 변하면then 방법이 지정한 리셋 함수를 호출합니다

  • 4
  • 비동기적으로 오류가 발생하면 상태가 Rejected로 변하고catch 방법이 지정한 리셋 함수를 호출하여 이 오류를 처리합니다

  • 4
  • 또한then 방법이 지정한 리셋 함수는 실행 중 오류가 발생하면catch 방법에 의해 포착됩니다
  • getJSON("/posts.json").then((posts)=>{
      // ...
    }).catch(//   getJSON    
      error=>console.log(' !', error);
    );
    

    Promise 상태가 Resolved로 변경되면 오류를 다시 던지는 것은 무효입니다.
    프로미스 대상의 오류는'거품'성격을 띠고 있어 포획될 때까지 뒤로 전달된다.실수는 항상 다음catch 문장에 포착된다는 뜻이다.
    getJSON("/post/1.json").then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // some code
    }).catch(function(error) {
      //  Promise 
    });
    

    일반적으로 then 방법에서 Reject 상태의 리셋 함수 (즉 then의 두 번째 인자) 를 정의하지 말고,catch 방법을 항상 사용합니다.
    전통적인try/catch 코드 블록과 달리catch 방법으로 오류 처리의 리셋 함수를 지정하지 않으면Promise 대상이 던진 오류는 외부 코드로 전달되지 않고 아무런 반응도 일어나지 않는다.
    catch 방법이 되돌아오는 것은Promise 대상이기 때문에then 방법을 이어서 호출할 수 있습니다.
    다음 코드에서 두 번째catch 방법은 이전 catch 방법이 던진 오류를 포착하는 데 사용됩니다.
    someAsyncThing().then(
      ()=>someOtherAsyncThing();
    ).catch(function(error) {
      console.log('oh no', error);
      //  , y 
      y + 2;
    }).catch(
      error=>console.log('carry on', error);
    );
    // oh no [ReferenceError: x is not defined]
    // carry on [ReferenceError: y is not defined]
    

    3)Promise.all()


    Promise.all 방법은 여러 개의 Promise 실례를 새로운 Promise 실례로 포장하는 데 사용됩니다.
    Promise.all 방법은 하나의 수조를 매개 변수로 받아들인다. p1, p2, p3은 모두Promise 대상의 실례이다. 그렇지 않으면 다음에 말한 Promise를 먼저 호출한다.resolve 메서드, 매개변수를 Promise 인스턴스로 변환한 다음 더 자세히 처리합니다.(Promise.all 방법의 매개 변수는 그룹이 아닐 수 있지만 Iterator 인터페이스가 있어야 하고 되돌아오는 모든 구성원은 Promise의 실례가 되어야 한다.)
    var p = Promise.all([p1, p2, p3]);
    

    p의 상태는 p1, p2, p3에 의해 결정되고 두 가지 상황으로 나뉜다.
    4
  • p1, p2, p3의 상태만 모두fulfilled로 변하고 p의 상태는fulfilled로 변한다. 이때 p1, p2, p3의 반환값은 하나의 수조를 구성하여 p의 리셋 함수에 전달한다

  • 4
  • p1, p2, p3 중 하나만rejected가 있으면 p의 상태는rejected가 된다. 이때 첫 번째reject의 실례적인 반환값은 p의 리셋 함수에 전달된다

  • 4)Promise.race()


    마찬가지로 여러 개의 Promise 인스턴스를 하나의 새로운 Promise 인스턴스로 포장합니다.
    var p = Promise.race([p1, p2, p3]);
    

    위 코드에서 p1, p2, p3 중 하나의 실례가 먼저 상태를 바꾸면 p의 상태는 따라서 바뀐다.먼저 바뀐 Promise 실례의 반환값은 p의 리셋 함수에 전달됩니다.

    5)Promise.resolve()


    기존 객체를 Promise 객체, Promise로 전환해야 하는 경우가 있습니다.resolve 방법이 이 역할을 한다.
    var jsPromise = Promise.resolve($.ajax('/whatever.json'));
    

    Promise.resolve 메서드의 매개 변수는
    4
  • 매개 변수는 Promise의 예입니다. 그러면 Promise.resolve는 아무런 수정도 하지 않고 그대로 이 실례를 되돌려줍니다

  • 4
  • 매개 변수는 thenable 대상이다. thenable 대상은then 방법을 가진 대상을 가리킨다.이 대상을 Promise 대상으로 바꾸고 thenable 대상의then 방법을 즉시 실행합니다

  • 4
  • 매개 변수는then 방법을 가진 대상이 아니거나 전혀 대상이 아니다:Promise.resolve 메서드는 Resolved 상태로 새 Promise 객체를 반환합니다

  • 4
  • 매개 변수가 없음: Resolved 상태의 Promise 객체를 직접 반환합니다.Promise 대상을 원한다면, 비교적 편리한 방법은 바로 Promise를 직접 호출하는 것이다.resolve 방법

  • 6)Promise.reject()


    Rejected 상태로 새 Promise 인스턴스를 반환합니다.매개변수 사용법은 Promise.resolve 방법이 완전히 일치합니다.

    7)Promise.try()


    동기식 함수를 동기식으로 실행하고 비동기식 함수를 비동기적으로 실행하며 통일된 API를 가지도록 한다.
    const f = () => console.log('now');
    Promise.try(f);
    console.log('next');
    // now
    // next
    

    Promise 때문에.try는 모든 조작에 통일된 처리 메커니즘을 제공하기 때문에then 방법으로 절차를 관리하려면 Promise를 사용하는 것이 좋다.try 포장해.이상을 더 잘 관리할 수 있다.
    사실, Promise.try는 아날로그try 코드 블록, 예를 들어promise.catch가 시뮬레이션한 것은catch 코드 블록입니다.

    8) 추가 방법:done()


    Promise 대상의 리셋 체인은 then 방법이나catch 방법으로 끝나든지 마지막 방법이 오류를 던지면 포착할 수 없습니다. (Promise 내부의 오류가 전체 국면에 퍼지지 않기 때문입니다.)따라서, 우리는 항상 리셋 체인의 끝부분에 위치하고, 발생할 수 있는 모든 오류를 제거하는 방법을 제공할 수 있다.
    asyncFunc()
      .then(f1)
      .catch(r1)
      .then(f2)
      .done();
    

    구현 코드:
    Promise.prototype.done = function (onFulfilled, onRejected) {
      this.then(onFulfilled, onRejected)
        .catch(function (reason) {
          //  
          setTimeout(() => { throw reason }, 0);
        });
    };
    

    9) 추가 방법:finally()


    Promise 객체의 마지막 상태에 관계없이 수행되는 작업을 지정할 수 있습니다.done 방법과 가장 큰 차이점은 일반적인 리셋 함수를 매개 변수로 받아들여 이 함수는 어쨌든 실행해야 한다는 것이다.예:
    server.listen(0)
      .then(function () {
        // run test
      })
      .finally(server.stop);
    

    구현 코드:
    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value  => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      );
    };
    

    4. 적용


    1) 이미지 로드


    그림의 불러오기를 Promise로 작성합니다. 불러오기가 완료되면 Promise의 상태가 바뀝니다.
    const preloadImage = function (path) {
      return new Promise(function (resolve, reject) {
        var image = new Image();
        image.onload  = resolve;
        image.onerror = reject;
        image.src = path;
      });
    };
    

    2) Generator 함수와 Promise의 결합


    Generator 함수 관리 프로세스를 사용하면 비동기적인 작업을 할 때 보통 Promise 대상을 되돌려줍니다.

    좋은 웹페이지 즐겨찾기