ES6 Promise 소개

7102 단어 웹 프런트엔드

ES6 Promise 소개


Promise는 비동기 프로그래밍의 해결 방안으로 전통적인 해결 방안인 리셋 함수와 사건보다 더욱 합리적이고 강력하다.

기본용법

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/*   */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}).catch(err){
  // failure
};  

개요


Promsie는 함수가 실행될 때의pending, 성공할 때의resolved(fulfilled), 실패할 때의rejected 등 세 가지 상태가 있다.
Promise는 리셋 함수를 매개 변수로 받아들여 즉시 실행합니다.매개 변수 수신 시스템이 전송하는 두 함수를 매개 변수로 리셋합니다:resolve와reject는 각각promise의 상태를 성공과 실패로 바꾸는 데 사용됩니다.
조건에 따라resolve 함수를 호출할 때, 아래promise에서 호출합니다.then () (의 첫 번째 매개 변수 리셋) 은 조건에 따라reject 함수를 호출하거나 오류를 던질 때 아래promise에서 받아들입니다.catch () (또는promise.then의 두 번째 인자 리셋) 를 수신합니다.then과catch의 리셋 함수를 수신하기 위해 이 두 함수에 매개 변수를 전달할 수 있습니다.resolve 함수가 없으면, then의 내용은 영원히 실행되지 않습니다.
이렇게 하면 then/catch 방법 내의 리셋은 Promise 구조기에 전달된 리셋 함수가 실행된 후에 실행될 것을 보장할 수 있다.

Promise 객체 특징

  • 대상의 상태는 외부의 영향을 받지 않는다
  • 일단 상태가 바뀌면 다시 변하지 않는다

  • Promise 객체의 단점:

  • Promise를 취소할 수 없습니다. 새로 만들면 바로 실행되고 중간에 취소할 수 없습니다
  • 리셋 함수를 설정하지 않으면 Promise 내부에서 던진 오류가 외부에 반영되지 않습니다..
  • Pending 상태에 있을 때 현재 어느 단계까지 진전되었는지 알 수 없다(막 시작했는지 곧 완성될 것이다)

  • 대표적인 예


    ajax


    다음은 Promise를 통해 ajax를 실현하는 예입니다.
    var getJSON = function(url) {
      var promise = new Promise(function(resolve, reject){
        var client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
    
        function handler() {
          if (this.readyState !== 4) {
            return;
          }
          if (this.status === 200) {
            resolve(this.response);
          } else {
            reject(new Error(this.statusText));
          }
        };
      });
    
      return promise;
    };
    
    getJSON("/posts.json").then(function(json) {
      console.log('Contents: ' + json);
    }, function(error) {
      console.error(' ', error);
    });
    

    serise 구현


    전통적인 방법


    우리는 jquery를 사용하여 aax 요청을 진행한다. 마지막에 두 개의 aax 요청으로 얻은 데이터가 필요하다. 전통적인 방법은 대략 이렇게 할 것이다.
       $.get('/test', null, function (data) {
            $.get('/test2', null, function (data2) {
                console.log(data+':'+data2);
            })
        });
    

    Promise 솔루션


    Promise는 더 나은 솔루션을 제공합니다.
    var p1 = new Promise(function (resolve, reject) {
        $.get('/test', null, function (data) {
            console.log(data);
            resolve(data);
        });
    });
    
    var p2 = new Promise(function (resolve, reject) {
        $.get('/test2', null, function (data2) {
            console.log(data2);
            resolve(data2);
        })
    });
    
    
    Promise.all([p1, p2]).then(function (arr) {
        console.log(arr[0]+':'+arr[1])
    });
    

    Promise.all 방법은 여러 개의 Promise 실례를 새로운 Promise 실례로 포장하는 데 사용됩니다.이 두 개의 실례의 상태가fulfilled로 변하거나 그 중 하나가rejected로 바뀌어야만 Promise를 호출할 수 있습니다.all 방법 뒤에 있는 리셋 함수입니다.
    이에 비해 Promise는 정적 레이스 방법을 제공하여 하나의 실례가 완성되면 then의 방법을 실행합니다.

    폭포를 이루다


    전통적인 방법


    우리는 jquery를 사용하여 aax 요청을 합니다. 두 번째 리셋 함수가 첫 번째 리셋 함수의 리셋 값을 원시 데이터로 필요로 할 때 원시 js 코드는 대략 이렇게 합니다.
    $.get('/test', null, function (data) {
        $.get('/test2', null, function (data2) {
            if(data === 'ok'){
                console.log("It's okay " + data2)
            }else{
                console.log('not okay')
            }
        })
    });
    

    두 개의 리셋 함수가 대처할 수 있는데, 만약 세 개, 네 개, 심지어 다섯 개가 있다면, 어려움을 피하기 어렵다.Promise는 다음과 같은 솔루션을 제공합니다.

    제1안

        var pro = new Promise(function (resolve, reject) {
    
            console.log('pro ');
    
            //  pro2 pro 
            setTimeout(function () {
                $.get('/test', null, simpleHandler);
            },5000);
    
            function simpleHandler(data) {
                resolve(data);
            }
        });
        var pro2 = new Promise(function (resolve, reject) {
    
            console.log('pro2 ');
    
            $.get('/test2', null, simpleHandler);
    
            function simpleHandler(data) {
    
                console.log('pro2 simpleHandler ');
    
                pro.then(function (data1) {
    
                    console.log('pro !');
    
                    if (data1 === 'ok') {
                        resolve(data);
                    } else {
                        reject(data)
                    }
                })
            }
        });
    
        pro2.then(function (data) {
            console.log("It's okay " + data);
        });
    

    출력 순서:
     console.log('pro ');
     console.log('pro2 ');
     console.log('pro2 simpleHandler ');
    
     5s
    
     console.log('pro !');    
     console.log("It's okay John Doe");
    

    이를 통해 알 수 있듯이 한 Promise 대상의 리셋에 다른 Promise 대상이 도입되면 도입된 Promise 대상이 실행되기를 기다립니다.

    두 번째 솔루션

    var getData = function () {
        return new Promise(function (resolve, reject) {
    
            console.log('pro ');
    
            //  pro2 pro 
            setTimeout(function () {
                $.get('/test', null, simpleHandler);
            },5000);
    
            function simpleHandler(data) {
                resolve(data);
            }
        });
    };
    
    var getData2 = function (data1) {
        return new Promise(function (resolve, reject) {
    
            console.log('pro2 ');
    
            $.get('/test2', null, simpleHandler);
    
            function simpleHandler(data) {
    
                console.log('pro2 simpleHandler ');
    
                    if (data1 === 'ok') {
                        resolve(data);
                    } else {
                        reject(data)
                    }
            }
        });
    };
    
    getData().then(function (data1) {
        return getData2(data1);
    }).then(function (data) {
        console.log("It's okay " + data);
    });
    

    체인식 then을 사용하면 순서에 따라 호출되는 리셋 함수를 지정할 수 있습니다.이때 이전 리셋 함수는 Promise 대상(즉 비동기적인 조작)이 되돌아올 수 있습니다. 이때 다음 리셋 함수는 이 Promise 대상의 상태가 바뀌기를 기다려야 호출됩니다.형식:
    pro1.then(()=>pro2).then(()=>pro3).then(... ...);
    

    괄전 방법


    done


    만약promise 방법 체인의 마지막 리셋 함수에 오류가 발생하면promise의 메커니즘으로 인해 우리는 알 수 없기 때문에done 방법을 총괄하여 리셋 체인의 끝에 있을 수 있습니다.
    asyncFunc().then(f1) .catch(r1) .then(f2).done();
    
    Promise.prototype.done = function (onFulfilled, onRejected) {
      this.then(onFulfilled, onRejected)
        .catch(function (reason) {
    
        });
    };
    

    finally


    오류가 발생하든 안 발생하든 마지막에 실행되는 방법
    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value  => {callback(value)},
        reason => {callback(reason)}
      );
    };
    

    좋은 웹페이지 즐겨찾기