개요
1. Promise를 어따써?
2. Promise의 기본
3. fetch에서 사용하기
1. Promise를 어따써?
리액트 프로젝트를 하다가, fetch API를 사용하게 되면서 Promise에 대해 알아야 한다.
Pomise는 ECMAScript6부터 추가되었고, 비동기 처리를 간결하게 하기 위해서 사용된다.
기본적으로 자바스크립트는 싱글스레드로, 동기적으로 처리된다. 그러나 setTimeout 이나 addEventListenter 메서드는 비동기로 실행되는데
console.log("A");
setTimeout(function() {console.log("B"),0};
console.log("C");
위와 같은 코드가 있을때, A->C->B 손서로 콘솔에 표시된다.
왜냐면, 말했다시피 setTimeout은 비동기적 처리를 하기 때문에 설정된 시간이 흐룬 후 실행하도록 '예약' 만 해놓고
다음 코드로 넘어간다. 그러니 콘솔에 A 찍어 -> 0초뒤에 콘솔에 B찍어 -> 콘솔에 C찍어 와 같은 명령을 수행하는것이다.
그런데, 생각해 볼 점은 setTimeout의 설정시간이 0초임에도 C가 먼저 찍혔다는 것이다.
0초후에 실행하라는건, 결국 바로 실행하라는건데 왜 C가 먼저 찍혔지? 하는 의문!
setTimeout은 비동기 처리를 하므로 아무리 시간 설정을 0초로 했더라도 예약만 걸어놓고 넘어가서
뒤에 남아있는 코드 작업을 먼저 끝내놓고! 다~ 끝난후에야 비로소 '0초 후'를 작동시키기 때문이다.
아무튼 비동기처리는 이런식으로 진행이 되는데, 서버와 통신할때 이런방식으로 진행된다고 생각해보다.
우리는 데이터를 서버에서 받아서 렌더링까지 해줘야하는데, 데이터를 받아오는 '예약'만 걸어두고 렌더링 코드를 진행해버리면 당연히 작동이 제대로 될 리가 없다. 이와같이 실행순서가 중요한 상황에서는 비동기 처리의 실행순서를 제어해줘야 하는데... 이럴때 사용되는 것이 콜백함수이지만, 순서제어를 위해서 콜백함수를 중첩해서 사용하다 보면 작업내용을 이해하기가 어려워지고 '콜백지옥' 에 빠지게 된다..
그래서 Promise를 사용하는 것이다.
2. Promise의 기본
promise는 비동기 처리를 실행하고 그 처리가 끝난 후에, 다음처리를 실행하기 위한 용도로 사용한다.
Promise는 객체이며, 실행하고자 하는 처리를 작성한 함수를 인수로 가진다. 그리고 그 함수는 resolve와 reject라는 인수를 받는다.
Promise 객체를 생성자를 통해 생성하면
const promise = new Promise(function(resolve,reject){ ... } );
이런 꼴이 된다.
객체긴 객체이나.. 함수리터럴을 가진? 함수를 promise로 래핑을 했다고 봐도 되려나?
아무튼, 인자로 받는 resolve와 reject도 콜백함수이다.
두가지 함수에는 어떠한 값이든 인수로 넘길 수 있으며 이 값은 다음 처리를 실행하는 함수에 전달된다.
여기까지만 생각해도, promise는 어떠한 함수들을 차례대로 수행하게 하고 있다는걸 알 수있다.
Promise에 넘긴 함수가 일련의 처리를 성공적으로 끝내면 resolve를 호출한다. resolve 메서드가 실행되면 Promise를 종료시키고, resolve에 인수로 넘긴 값을 then 메서드에 인수로 넘긴 함수에 전달되어 다음 처리를 위해 사용된다.
then 메서드에 넘어가는 함수는 성공콜백 함수 라고 하며, promise 안의 처리가 정상적으로 끝났을 때 호출된다.
그리고, 이 성공콜백 함수는 인수로 response를 받는다.
then 메서드의 첫번째 인수는 성공콜백함수, 두번째 인수는 실패콜백 함수이며 then메서드에서 처리할 내용과 catch 메서드에서 처리할 내용을 then 메서드 하나에서 작성할 수 있다!
1. Promise를 사용하면 그 즉시 Pending 상태가 된다 (대기상태)
2. 성공하면 .then() 으로 전달 된 함수가 호출되고 Resolved 상태
2-1. 실패하면 catch() 안으로 들어간 함수가 실행된다 Rejected
3. 그리고 then()이나 catch() 모두 Promise를 반환해서 그 뒤로 분기를 다시 then과 catch로 이어간다.
그러고보니, 정처기 공부할때 했던 프로세스와 메커니즘이 약간 비슷한거 같다
3. fetch() 에서 사용하기
fetch( resource) 는 Promise 타입의 데이터를 반환한다.
그리고 그 Promise 타입의 데이터는 Response 타입의 오브젝트를 반환한다.
1. Promise 객체는 두개의 메서드를 사용 할 수 있다 then과 catch이다.
2. then과 catch는 둘다 콜백함수를 인자로 받는데
3. 아까 위에서 설명한 것처럼.. then이 인자로 받는 콜백함수 -> 성공콜백함수!
따라서 fetch를 통해서 실행한 결과가 '성공'일때 then이 받는 콜백함수가 호출되게 되어있고, 그 결과값을 첫번째 파라미터로 받을 수 있다.
4. 반대로, fetch를 통해서 실행한 결과가 '실패'일때, catch가 받는 콜백함수가 호출 되게 되어있고 이것을 실패콜백함수라고 부르며, 그 결과값을 첫번째 인자로 받을 수 있다. (실패 reason 반환)
즉, Promise를 통해서 비동기처리를 하게 되면, 성공하게 되면 then으로 호출한 함수를.. 실패하면 catch에서 호출한 함수를 받는다던지.. 결과적으로 표준화된 처리를 할 수 있게 된다.
fetch 호출 -> promise 반환 -> 성공했으면 then 메서드 // 실패했으면 catch 함수를 타고 다시 Promise반환 ->
그러나 성공일때는 첫번째 인수로 결과값을 받을수 있고(response 객체), 실패일때는 실패에 대한 결과값을 받을 수 있다.
결국 fetch API로 서버와 통신에 성공하면 then을 타고 들어와서 reponse를 반환하는데,
response에는 서버와 통신 결과에 대한 정보들이 들어있따!
response가 가지고 있는 함수를 통해 json() 메서드를 호출 -> 웹브라우저는 json 타입에 맞게 해석해서 자바스크립트 데이터 타입으로 돌려주고 우리가 데이터를 잘 다룰 수 있게 해준다..
그런데, response.json()을 해줘도 결국 promise로 반환을 하는데! 그러면 또 뭘 할수 있겠습니까?
promise의 then과 catch를 호출 할 수 있게 되고... 그러면 또.. 콜백함수를 써서
response.json().then(function(data){...} 할 수 있게되는 것. 그럼 진짜진짜 최종적으로
response.json() 이 성공을 했다 라는건 데이터가 json으로 잘 들어온거니까
then의 성공콜백함수를 호출하게 되고 그 성공한 값을..data에 받아올 수 있게 된다.
너무너무 헷갈리는걸 ? .. 어차피 한번에 다 이해하기 힘드니까 이번시간에는 이정도로 스케치만 해두고
반복해서 이해해보자.. 혹시나 혹시나 티끌만한 가능성으로 이 글을 보는 분이 계시다면, 공부+ 셀프 이해 목적으로 작성된 글이오니 참고하지 말아주세요 ㅎㅎ
Promise 정리하고 다시 리액트 강의 듣는데, 몇번 돌이켜 생각할수록 더 꼬이는 것 같아서 다시 간단하게 정리!
'자바스크립트' 카테고리의 다른 글
코딩테스트 (0) | 2023.07.07 |
---|---|
[잔지식 채우기] 자바스크립트 코딩테스트 Lv2. 이진변환 반복하기 中 (0) | 2023.06.11 |
자바스크립트 : 페이지네이션에 사용하는 Array.fill().map() (0) | 2023.06.09 |