Language/JavaScript

프라미스

nayoon030303 2021. 7. 14. 19:46

콜백

프라미스가 나오게 된 배경을 설명해줍니다.
콜백 함수란 쉽게 설명해서 나중에 호출되는 함수입니다.

 

프라미스

프라미스란?

ES6에 도입된 기술입니다. 프라미스란 제작코드와 소비 코드를 연결해주는 특별한 자바스크립트 객체입니다. 프라미스는 시간이 얼마나 걸리든 상관없이 약속한 결과를 제작코드가 준비되었을 때, 모든 소비 코드가 결과를 사용할 수 있도록 해줍니다. 콜백함수가 해주는 일과 비슷하다고 할 수 있습니다.

let promise = new Promise(function(resoleve, reject){
  //executor 제작 코드
});
  • new Promise에 전달되는 함수는 executor(실행자, 실행함수)라고 부릅니다. executor는 new Promise가 만들어질 때 자동으로 실행되고 결과를 최종적으로 만들어 내는 제작 코드를 포함합니다.
  • resolve, reject 라는 자바스크립트에서 자체적으로 제공하는 콜백입니다.
  • 개발자는 resolvereject를 신경 쓰지 않고 executor안 코드만 작성하면 됩니다.
  • 개발자는 반드시 인수로 넘겨준 콜백(resolve,reject) 중 하나를 반드시 호출해야합니다.

resolve(value) - 일이 성공적으로 끝났을 경우 결과를 나타내는 value와 함께 호출
reject(error) - 에러가 발생한 경우 에러 객체인 error를 함께 호출

 

요약하자면 promise가 실행되면서 executor가 자동으로 실행됩니다. executor에서 결과 처리가 끝난다면 성공 여부에 따라서 resolve 또는 reject를 호출합니다.

 

프로미스 상태변화 

promise객체는 stateresult라는 내부 프로퍼티를 갖고 있습니다. 

  • state - 처음에는 pending(보류)였다가 resolve(value)가 호출된다면 "fulfilled", reject(error)가 호출된다면 rejected로 변환됩니다.
  • result - 처음에는 undefined 였다가 resolve(value)가 호출된다면 value로, reject(error)가 호출된다면 error로 변환됩니다.
모던자바스크립트-프로미스

 

 

result(value), reject(error)를 이용한 간단한 예제

 

resolve(value)를 이용한 예제

let promise = new Promise(function(resolve,reject){
	//1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 
    //state는 'fulfilled' result는 'done'이 됩니다. 
	
    setTimeout(()=>resolve("done"),1000);
});

 

reject(error)를 활용한 예제

let promise = new Promise(function(resolve,reject){
	//1초 뒤에 에러와 함께 실행이 종료되었다는 신호를 보냅니다. 
    //state는 'reject' value는'error'가 됩니다.
    
    setTimeout(()=>reject(new Error("에러 발생!")),1000);
});

 

위 예시를 통해서 알 수 있는 점

  1. executor는 new Promise에 의해 자동으로 그리고 즉각적으로 호출됩니다. 
  2. executor는 인자로 resolvereject 함수를 받습니다. 이 함수들은 자바스크립 엔진이 미리 정의한 함수이므로 개발자가 따로 만들 필요는 없습니다. 다만 resolvereject 중 하나는 반드시 호출해야 합니다. 

 

소비자: then, catch, finally

프라미스 객체는 executor('제작코드')와 결과가 에러를 받을 소비 함수를 이어주는 역할을 합니다. 소비함수는 .then, .catch, .finally메서드를 사용해서 등록됩니다.

 

then

.then은 프라미스에서 가장 중요하고 기본이 되는 메서드입니다.

then 메서드의 문법을 자세히 알고 싶다면 아래 사이트에서 공부하시길 바랍니다. 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/then 

 

Promise.prototype.then() - JavaScript | MDN

then() 메서드는 Promise (en-US)를 리턴하고 두 개의 콜백 함수를 인수로 받습니다. 하나는 Promise가 이행했을 때, 다른 하나는 거부했을 때를 위한 콜백 함수입니다.

developer.mozilla.org

 

성공적으로 이행된 프라미스에 반응 예시

 

프라미스가 성공적으로 이행된 경우 첫 번째 함수가 실행됩니다.

let promise = new Promise(function(resoluve,reject){
	setTimeout(()=>resolve("done"),1000);  
});

//resolve 함수는 .then의 첫 번째 함수(인수)를 실행합니다. 
promise.then(
	result=>alert(result), //1초후 "done"을 출력
    error=>alert(error)	   //실행되지 않음
);

 

프라미스가 거부된 경우 반응 예시

 

프라미스가 거부된 경우 두 번째 함수가 실행됩니다. 

let promise = new Promise(function(resolve,reject){
	setTimeout(()=>reject(new Error("에러 발생")),1000);
});

//reject 함수는 .then 두 번째 함수를 실행합니다. 
promise.then(
	result=>alert(result), //실행되지 않음
    error=>alert(error) //1초 후 "Error: 에러 발생!"를 출력
);

 

catch

에러가 발생한 경우만 다루고 싶다면. then(null, errorHandlingFunction)같이 null을 첫 번째 인수로 전달하면 됩니다. 

. catch(errorHandlingFunction)를 써도 되는데 .catch.then에 null을 전달하는 것 과 동일하게 작동합니다. 

 

let promise = new Promise(function(resolve, reject){
	setTimeout(()=>reject(new Error("에러 발생")),1000);
});

//.catch(f)는 promise.then(null,f)와 동일하게 작동합니다.
promise.catch(alert); //1초 뒤 "Error: 에러 발생!" 출력

 

finally

try catch절에 finally절이 있는 것처럼, 프라미스에도 finally가 있습니다. 프라미스가 처리되면(이행이나 거부) f가 항상 실행된다는 점에서 .finally(f).then(f,f)와 유사합니다. 

쓸모가 없어진 로딩 인디케이터(loading indicator)를 멈추는 경우같이, 결과가 어떻든 마무리가 필요하면 finally가 유용합니다. 

new Promise((resolve,reject)=>{
	//시간이 걸리는 어떤 일을 수행하고, 그 후 resolve, reject를 호출함
})
.finally(()=>로딩 인디케이터 중지)
.then(result=>result, error=>error)

 

 

프라미스를 사용한 코드가 콜백 기반 코드보다 좋은 점

프라미스 콜백
프라미스를 이용하면 흐름이 자연스럽습니다. 
결과에 따라 그 다음 .then에 무엇을 할지에 대한 코드를 작성할 수 있습니다.
함께 호출할 callback함수가 준비되어 있어야 합니다. 
정의된 함수를 호출하기 이전에 호출 결과로 무엇을 할지 미리 알고 있어야 합니다.
프라미스에 원하는 만큼 .then을 호출 할 수 있습니다. 
(자세한 내용은 프라미스 체이닝에서 다루겠습니다.)
콜백은 하나만 가능합니다

 

 


위의 내용들은 모던 자바스크립트 프라미스 내용을 기반으로 작성했습니다.