jQuery-12.Promise

이현주·2023년 10월 1일

web-frontend

목록 보기
26/26

Promise 객체

1. 비동기 처리의 결과(성공 또는 실패) 값을 나타낼 수 있는 객체이다.

     (비동기 처리를 할 때 응답이 올 때까지 기다리는 JavaScript 객체이다.)

2. Promise 상태

    1) 대기상태 : pending,   이행도 하지 않고 거부도 하지 않은 초기 상태
    2) 이행상태 : fulfilled, 비동기 처리가 성공적으로 완료된 상태
    3) 거부상태 : reject,    비동기 처리가 실패된 상태

3. Promise 메소드

    1) Promise.resolve() : 이행상태에서 호출하는 메소드이다. resolve() 메소드가 반환하는 프로미스는 then() 메소드를 따라가서 처리된다.
    2) Promise.reject()  : 거부상태에서 호출하는 메소드이다. reject() 메소드가 반환하는 프로미스는 catch() 메소드를 따라가서 처리된다.

Promise 객체 생성

var promise = new Promise(function(resolve, reject){

  // 랜덤으로 이행상태(성공)와 거부상태(실패)를 생성
  if(Math.random() < 0.5){
    resolve('이행');  // resolve() 메소드를 호출하면 then() 메소드에서 정의한 함수가 실행된다.
  } else {
    reject('거부');   // reject() 메소드를 호출하면 catch() 메소드에서 정의한 함수가 실행된다.
  }

});

Promise가 이행상태인 경우

promise.then(function(str){
  console.log(str + '상태');
})

Promise가 거부상태인 경우

promise.catch(function(str){
  console.log(str + '상태');
})

Promise 객체 생성 + then() 메소드 호출 + catch() 메소드 호출

new Promise(function(resolve, reject){
  $.ajax({
    type: 'get',
    url: 'product1.xml',
    async: true,
    dataType: 'xml',
    success: function(resData){
      resolve($(resData).find('product').length);  // resolve(3)
    },
    error: function(jqXHR){
      reject(jqXHR.status);  // reject(404)
    }
  })
}).then(function(length){
  console.log(length);
}).catch(function(status){
  console.log(status);
})

[12_Promise.html]

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="../../assets/js/lib/jquery-3.7.1.min.js"></script>
</head>
<body>
  
  <script>

    // 비동기 통신은 요청 이후에 응답을 기다리지 않는다!

    var a;  // a는 undefined
    $.ajax({
      type: 'get',
      url: 'product1.xml',
      async: true,
      dataType: 'xml',
      success: function(resData){
        a = $(resData).find('product').length;
      }
    })
    console.log(a);  // a는 3을 기대하지만, ajax 응답이 올 때까지 기다리지 않고 이 코드가 처리된다.

  </script>

  <script>

    /*
      Promise 객체
      1. 비동기 처리의 결과(성공 또는 실패) 값을 나타낼 수 있는 객체이다.
         (비동기 처리를 할 때 응답이 올 때까지 기다리는 JavaScript 객체이다.)
      2. Promise 상태
        1) 대기상태 : pending,   이행도 하지 않고 거부도 하지 않은 초기 상태
        2) 이행상태 : fulfilled, 비동기 처리가 성공적으로 완료된 상태
        3) 거부상태 : reject,    비동기 처리가 실패된 상태
      3. Promise 메소드
        1) Promise.resolve() : 이행상태에서 호출하는 메소드이다. resolve() 메소드가 반환하는 프로미스는 then() 메소드를 따라가서 처리된다.
        2) Promise.reject()  : 거부상태에서 호출하는 메소드이다. reject() 메소드가 반환하는 프로미스는 catch() 메소드를 따라가서 처리된다.
    */

    // Promise 객체 생성
    var promise = new Promise(function(resolve, reject){

      // 랜덤으로 이행상태(성공)와 거부상태(실패)를 생성
      if(Math.random() < 0.5){
        resolve('이행');  // resolve() 메소드를 호출하면 then() 메소드에서 정의한 함수가 실행된다.
      } else {
        reject('거부');   // reject() 메소드를 호출하면 catch() 메소드에서 정의한 함수가 실행된다.
      }

    });

    // Promise가 이행상태인 경우
    promise.then(function(str){
      console.log(str + '상태');
    })

    // Promise가 거부상태인 경우
    promise.catch(function(str){
      console.log(str + '상태');
    })

  </script>

  <script>

    // Promise 객체 생성 + then() 메소드 호출 + catch() 메소드 호출
    new Promise(function(resolve, reject){
      $.ajax({
        type: 'get',
        url: 'product1.xml',
        async: true,
        dataType: 'xml',
        success: function(resData){
          resolve($(resData).find('product').length);  // resolve(3)
        },
        error: function(jqXHR){
          reject(jqXHR.status);  // reject(404)
        }
      })
    }).then(function(length){
      console.log(length);
    }).catch(function(status){
      console.log(status);
    })

  </script>


  <hr>


  <!-- Promise 예시. ajax이 ajax을 호출하는 동작 시나리오 -->
  <script>
    
    /*
      동작 시나리오
      1. ajax1 : 입력한 이메일이 사용 가능한 이메일인지 확인한다. (DB에 등록된 이메일인지 여부 확인)
      2. ajax2 : 사용 가능한 이메일이라면 인증 메일을 보낸다.
    */

    function checkEmail(){
      return new Promise(function(resolve, reject){
        // 사용자의 이메일
        var email = 'admin@web.com';
        // 1. ajax1 : 입력한 이메일이 사용 가능한 이메일인지 확인한다. (DB에 등록된 이메일인지 여부 확인)
        $.ajax({
          type: 'get',
          url: 'validEmail.json',  // {"validEmail": true} 또는 {"validEmail": false}
          async: true,
          data: 'email=' + email,  // 사용자의 이메일을 서버로 보냄
          dataType: 'json',
          success: function(resData){
            if(resData.vaildEmail){
              resolve(email);
            } else {
              reject(email);
            }
          }
        })
      })
    }

    checkEmail().then(function(email){
      // 사용자가 입력한 인증코드
      var authcode = '654321';
      // 2. ajax2 : 사용 가능한 이메일이라면 인증 메일을 보낸다.
      $.ajax({
        type: 'get',
        url: 'authentication.json',  // {"authcode": "123456"} (의미: 사용자의 이메일로 보낸 인증코드)
        async: true,
        data: 'email=' + email,
        success: function(resData){
          if(authcode === resData.authcode){
            alert('인증되었습니다.');
          } else {
            alert('인증실패했습니다.');
          }
        }
      })
    }).catch(function(email){
      alert(email + ' 이메일은 이미 등록되었습니다.');
    })

  </script>


  <hr>


  <!-- Promise 예시. 이미지 표시하기 -->
  <div>
    <button id="btn">이미지열기</button>
    <div id="img"></div>
  </div>
  <script>
    
    $('#btn').click(function(){
      var no = parseInt(Math.random() * 10 + 1);  // 1 ~ 10 사이의 랜덤 값 생성
      openImage('../../assets/image/animal' + no + '.jpg');
    })

    function openImage(imageURL){
      new Promise(function(resolve, reject){
        // ajax을 이용해서 이미지를 blob(Binary Type, 이진타입) 타입으로 가져오기
        $.ajax({
          type: 'get',
          url: imageURL,
          async: true,
          xhrFields: {
            responseType: 'blob'
          },
          success: function(resData){  // resData에는 이미지의 이진 데이터가 전달됨
            resolve(resData);
          },
          error: function(jqXHR){
            reject(jqXHR);
          }
        })
      }).then(function(resData){
        var img = new Image();  // <img> 태그를 만드는 JavaScript 객체
        img.src = URL.createObjectURL(resData);  // 이미지의 이진 데이터를 <img> 태그로 만든 뒤 가상 주소를 src 속성에 넘긴다.
        $('#img').empty();
        $('#img').append(img);
      }).catch(function(jqXHR){
        alert(jqXHR.status + '(' + jqXHR.statusText + ')');
      })
    }

  </script>


</body>
</html>

[authentication.json]

{
  "authcode":"123456"
}

[validEmail.json]

{
  "validEmail":true
}

profile
졸려요

0개의 댓글