ES6 필수 사항 (5) Promise 객체

7004 단어
Promise 객체
1. Promise 객체는 ES6의 비동기 프로그래밍 솔루션으로 다음과 같은 두 가지 특징이 있습니다.
  • Promise 대상은 비동기적인 조작을 대표한다. Pending(진행 중), Resolved(완성,Fulfilled)와 Rejected(실패)만 있고 이 상태는 외부의 영향을 받지 않는다
  • Promise 대상의 상태가 바뀌는 것은 두 가지가 가능하다. 펜딩에서 Resolved로 바뀌거나 펜딩에서 Rejected로 바뀌거나 상태가 바뀌면 다시 변하지 않고 언제든지 이 결과를 얻을 수 있다
  • 2. Promise 객체의 단점:
  • Promise 객체가 새로 만들어지면 즉시 실행되며 중도에 취소할 수 없음

    let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    resolve();
    });
    // Promise
  • 프로미스 대상의 리셋 함수를 설정하지 않으면 프로미스는 내부에서 오류를 던져 외부, 즉 외부에서 오류 알림을 받지 못한다
  • Promise 대상이 Pending 상태일 경우 포획이 어느 단계까지 진행되었는지 알 수 없음(방금 시작했는지 완료 예정)
  • 3. Promise 대상은 하나의 구조 함수로 Promise 실례를 생성하는데 사용된다. 다음은 하나의 Promise 실례를 창조한 예이다.
    let promise = new Promise(function(resolve, reject) {
      // ... to do
    
      if ( success ){
        resolve(value);    // 
      } else {
        reject(error);     // 
      }
    });
    

    ps:Promise 구조 함수는 하나의 함수를 매개 변수로 받아들인다. 이 함수의 두 매개 변수는 각각 Resolve와reject로 성공과 실패의 리셋을 처리하는 데 사용된다.
    4. Promise 실례가 생성된 후에 then 방법으로 Resolved 상태와 Reject 상태의 리셋 함수를 각각 지정할 수 있다.
    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    });
    

    ps:then 방법은 두 개의 리셋 함수를 매개 변수로 받아들일 수 있습니다.첫 번째 리셋 함수는 Promise 대상의 상태가 Resolved로 변할 때 호출되고 두 번째 리셋 함수는 Promise 대상의 상태가 Rejected로 변할 때 호출되며 그 중에서 두 번째 함수는 선택할 수 있다.
    5.resolve 함수의 매개 변수는 정상적인 값을 제외하고 다른 프로미스 실례일 수도 있다. 이는 비동기적인 조작의 결과가 하나의 값일 수도 있고 다른 비동기적인 조작일 수도 있음을 나타낸다.
    let promise1 = new Promise(function (resolve, reject) {
      // ...
    });
    
    let promise2 = new Promise(function (resolve, reject) {
      // ...
      resolve(p1);
    })
    

    위 코드는 하나의 비동기 조작의 결과가 다른 비동기 조작으로 되돌아오면promise1의 상태는promise2에 전달되고promise1의 상태가Pending이면promise2의 리셋 함수는promise1의 상태 변화를 기다린다.만약promise1의 상태가 Resolved 또는 Rejected가 되었다면promise2의 리셋 함수는 즉시 실행될 것입니다.
    6. Promise 실례 방법 then은 새로운 Promise 실례로 되돌아오기 때문에 체인식 쓰기, 즉 then 방법 뒤에 다른 then 방법을 호출할 수 있다
    let promise = new Promise(function (resolve, reject) {
      // ...
    })
    promise.then(function(res) {
       return res.post;
    }).then(function(post) {
       // ...
    });
    

    ps: 상례에서 순서대로 두 개의 리셋 함수를 지정했는데 첫 번째 리셋 함수가 완성되면 리셋 결과를 매개 변수로 하고 두 번째 리셋 함수로 전송한다. 만약에 리셋이 프로미스 대상(즉 비동기적인 조작이 있음)이면 그 다음 리셋 함수는 이 프로미스 대상의 상태가 바뀌기를 기다려야 호출된다.
    let promise = new Promise(function (resolve, reject) {
      // ...
    })
    promise.then(function(res) {
       return new Promise(/.../);
    }).then(function(res) {
       // Resolved
    },function(error){
       // Rejected
    });
    

    7.Promise.prototype.catch 방법은 오류가 발생했을 때의 리셋 함수를 지정하는 데 사용됩니다. 비동기적으로 오류가 발생할 뿐만 아니라, then 방법이 지정한 리셋 함수도 실행 중 오류가 발생하면catch 방법에 포착됩니다.
    let promise = new Promise(function(resolve, reject) {
        throw new Error('test');
    }).catch(function(error) {
      console.log(error);
    });
    
    // Error: test
    

    8. Promise 상태가 Resolved로 변경된 경우 오류를 다시 던지면 무효
    let promise = new Promise(function(resolve, reject) {
      resolve('ok');
      throw new Error('test');
    });
    promise
      .then(function(value) { console.log(value) })
      .catch(function(error) { console.log(error) });
      
      //ok
    

    ps: 상기 결과는 앞서 언급한 Promise의 상태가 바뀌면 영구적으로 이 상태를 유지하고 변하지 않기 때문에 Resolve 문장 뒤에서 오류를 던지면 포획되지 않습니다
    9. Promise 대상의 오류는'거품'성질을 가지고 포획될 때까지 뒤로 전달되기 때문에 항상 catch 방법을 사용하고then 방법의 두 번째 파라미터를 사용하지 않는 것을 권장합니다. 왜냐하면 catch 방법을 사용하면 앞의 then 방법 실행 중의 오류를 포획할 수 있기 때문입니다.
    // bad
    promise
      .then(function(data) {
        // success
      }, function(err) {
        // error
      });
    
    // good
    promise
      .then(function(data) { //cb
        // success
      })
      .catch(function(err) {
        // error
      });
    

    10.Promise.all 방법은 여러 개의 Promise 실례를 새로운 Promise 실례로 포장하는 데 사용됩니다. 이 방법은 하나의 Promise 대상의 그룹을 매개 변수로 받아들여 이 그룹의 모든 Promise 대상이 Resolve나reject 상태로 변할 때 호출됩니다.then 방법.
    var p1 = new Promise(function (resolve) {
        setTimeout(function () {
            resolve("Hello");
        }, 3000);
    });
    
    var p2 = new Promise(function (resolve) {
        setTimeout(function () {
            resolve("World");
        }, 1000);
    });
    
    Promise.all([p1, p2]).then(function (result) {
        console.log(result);    // ["Hello", "World"]
    });
    

    위의 예는 두 데이터를 전송하는 데 서로 다른 시간이 필요한 것을 시뮬레이션했다. 비록 p2의 속도는 p1보다 빠르지만Promise.all 방법은 수조 안의 순서에 따라 결과를 되돌려주지만promise 자체는 하나하나의 순서로 집행되는 것이 아니라 동시에 시작하고 병행적으로 집행되는 것이다. 이 특징을 이용하여 여러 개의 리셋이 되돌아와야만 할 수 있는 조작을 처리할 수 있다.
    11.Promise.race 메서드 및 Promise.all 방법은 유사하고 하나의 프로미스 대상 그룹을 매개 변수로 받아들인다. 다른 것은 이 그룹의 프로미스 대상의 상태가 바뀌면 (resolve나reject) 이 방법이 되돌아온다는 것이다.

    var p1 = new Promise(function (resolve) {
    setTimeout(function () {
    resolve("Hello");
    }, 3000);
    });
    var p2 = new Promise(function (resolve) {
    setTimeout(function () {
    resolve("World");
    }, 1000);
    });
    Promise.race([p1, p2]).then(function (result) {
    console.log(result); // Wrold
    });

    12. 일반적인 상황에서 우리는 new Promise () 를 사용하여promise 대상을 만들 수 있으며, 이외에 Promise를 사용할 수 있다.resolve 및 Promise.프로젝트 두 가지 방법;
  • 정적 메소드 Promise.resolve(value)는 new Promise() 방법의 단축키

    let promise = Promise.resolve('resolved');
    //
    let promise = new Promise(function(resolve){
    resolve('resolved');
    });
    로 볼 수 있습니다. 상기 promise 대상은 즉시 확정(즉resolved) 상태에 들어가'resolved'를 뒤에 then에서 지정한 onFulfilled 함수에 전달합니다.

    Promise.resolve('resolved').then(function(value){
    console.log(value);
    });
    // resolved
  • Promise.reject(error)는 및 Promise입니다.resolve(value)와 유사한 정적 방법은 new Promise() 방법의 단축키입니다.

    let promise = Promise.reject(new Error(" "));
    //
    let promise = new Promise(function(resolve,reject){
    reject(new Error(" "));
    });
    상기 promise 대상은then이 지정한 onRejected 함수를 통해 오류(Error) 대상을 이 onRejected 함수

    Promise.reject(new Error("fail!")).catch(function(error){
    console.error(error);
    });
    // Error : fail!
  • 에 전달한다.
    13. 프로미스를 실제 개발에 활용할 수 있다. 다음은 밤을 몇 개 들어보자.
    // 
    const preloadImage = function (path) {
      return new Promise(function (resolve, reject) {
        var image = new Image();
        image.onload  = resolve(image);
        image.onerror = function() {
            reject(new Error('Could not load image at ' + path));
        };
        image.src = path;
      });
    }
    
    // 
    function reader (file) {
      return new Promise(function (resolve, reject) {
        let reader = new FileReader();
    
        reader.onload = function () {
          resolve(reader);
        };
        reader.onerror = function() {
            reject(new Error('Could not open the file ' + file));
        };
    
        if (!file.type || /^text\//i.test(file.type)) {
          reader.readAsText(file);
        } else {
          reader.readAsDataURL(file);
        }
      })
    }

    좋은 웹페이지 즐겨찾기