TIL # 121 : [JavaScript] 들숨에 비동기 날숨에 처리 (2) : Promise

셀레스틴 허·2021년 4월 28일
0
post-thumbnail
post-custom-banner

자바스크립트 엔진은 싱글 스레드다. 그래서 동시에 두 가지 작업릉 할 수 없음, 여러 작업이 동시에 요청이 들어올 때 이 전 작업이 마무리 될 때까지 대기한다.

Promise?

기본 개념

  • 비동기를 간단하게 처리할 수 있도록 도와주는 Object
  • 콜백 함수로 처리하던 구조에서 new Promise(), resolve(), then()로 바꿀 수 있음

Promise State

  • 기본적으로 프로미스는 3가지 상태(처리 과정)가 있음
    ++ pending - 비동기 처리 로직이 아직 완료되지 않은 상태
    ++ fulfilled - 비동기 처리가 완료되어 프로미스가 결과값을 반환해준 상태, fulfilled 상태가 되면 .then()으로 처리 결과값을 받을 수 있다
    ++ rejected - 비동기 처리가 실패하거나 오류가 발생한 상태, .catch()으로 에러핸들링 해줄 수 있다 (가급적 .catch()으로 에러를 잡자)
    new Promise(); // pending state
    
    new Promise(function(resolve, reject) {
    	
    }); // new Promise method with callback function
    
    new Promise(function(resolve, reject) {
    	resolve();
    }); // fulfilled state

	function getDate() {
    	return new Promise(function (resolve, reject) {
        	var data = 100;
          	resolve(data);
        }); 
    }; // .then()으로 처리 결과값 받음
	
	getData().then(function (resolvedData) {
    	console.log(resolvedData);
    }); // 100

    new Promise(function (resolve, reject) {
      reject();
    }); // rejected state

    function getData() {
      return new Promise(function (resolve, reject) {
        reject(new Error('Failed'));
      });
    }; 

    getData().then().catch(function(err){
      console.log(err)
    }) // reject()의 결과값을 받음

Promise Example

var timeAttack = new Promise(function (resolve, reject) {
  setTimeout(function () {
    var ran = Math.random() * 10;
    if (ran >= 5) {
      resolve(ran);
    } else {
      reject(new Error('Failed'));
    }
  }, 3000);
});


timeAttack.then(function (num) {
  console.log(num + ' complete!');
}, function () {
  console.log('error');
}) // then의 두번째 인자로 에러 핸들링

timeAttack.then(function (num) {
  console.log(num + ' complete!')
}).catch(function (err) {
  console.log(err);
}); // .catch()으로 에러 핸들링

  • 프로미스 객체 뒤에 .then()을 붙여 작업의 결과값을 실행한다
  • .catch()으로 error 핸들링 가능

Promise Chaining

var timeAttack = new Promise(function (resolve, reject) {
  setTimeout(function () {
    var ran = Math.floor(Math.random() * 10);
    if (ran >= 5) {
      resolve(ran);
    } else {
      reject(new Error('Failed'));
    }
  }, 1000);
});

timeAttack
  .then(function (num) {
    console.log(num)
    return num + 10 
  }) // 7
  .then(function (num) {
    console.log(num)
    return num + 100 
  }) // 17
  .then(function (num) {
    console.log(num)
  }) // 117

finally?

  • Promise가 처리되면 충족되거나 거부되는지 여부에 관계 없이 지정된 콜백 함수가 실행됨
  • 성공적으로 이행, 거절됐는지와 관계없이 Promise가 처리 된 후에 코드가 무조건 한번은 실행됨

finally 예제 코드

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.log(error); })
  .finally(function() { isLoading = false; });

위에 있는 코드에도 적용해보면

var timeAttack = new Promise(function (resolve, reject) {
  setTimeout(function () {
    var ran = Math.floor(Math.random() * 10);
    if (ran >= 5) {
      resolve(ran);
    } else {
      reject(new Error('Failed'));
    }
  }, 1000);
});

timeAttack
  .then(function (num) {
    console.log(num)
    return num + 10 
  })
  .then(function (num) {
    console.log(num)
    return num + 100 
  })
  .then(function (num) {
    console.log(num)
  })
  .catch(function (err) {
    console.log(err);
  })
  .finally(function (num) {
  console.log('FINALLY');
}); 

Error가 났음에도 출력됨:

성공적으로 실행돼도 출력됨:

Reference:
https://velog.io/@cyranocoding/2019-08-02-1808-%EC%9E%91%EC%84%B1%EB%90%A8-5hjytwqpqj
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
앨리님 https://www.youtube.com/watch?v=JB_yU6Oe2eE
캡판님 https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

profile
Software Developer / 고통은 필연, 괴로움은 선택
post-custom-banner

0개의 댓글