[Javascript] 뭐하는 애인지 헷갈리는 Promise
Promise는 설명하기 헷갈리는 녀석이다.
개발을 하다 보면 내부적으로 Promise를 리턴하는 다양한 함수를 사용하게 되는데, (ex: fetch, axios) 이때
리턴된 값의 형태가 영 익숙하지 않다?
리턴된 값으로 뭘 어떻게 해야 할지 모르겠다?
나는 비동기 함수가 처리된 다음에 '값'을 받아오고 싶었는데 이상한 놈이 리턴됐다?
하는 사람들을 많이 봤다.
모두 Promise가 뭔지 모르기 때문에 나오는 반응이다.
Promise는 함수인지, 객체인지도 처음엔 헷갈리고
new Promise를 통해 객체를 생성할 때 전달하는 resolve, reject도
어떻게 쓰는지 잘 모르겠는, 딱 보는 순간엔 읭 스러운 녀석이다.
하지만 자바스크립트에서 비동기 로직을 다룰 때, 해당 비동기 작업이 끝난 것을 확인한 후에 어떤 작업을 하고싶은 경우
이 Promise를 모른다면 계속 무의미한 삽질을 하거나 남의 코드를 확인해가며 프로그램을 짜야하는 불편함이 생긴다.
한 번 이해해보면 별 것도 아닌 Promise를 알아보자.
1. Promise가 뭐지?
Promise는 비동기 작업이 끝났을 때 그 작업이 성공했는지, 실패했는지 여부에 따라
수행될 함수를 등록할 수 있는 객체다.
promise객체를 생성하는 방법은 new연산자를 이용하는 방법이 있다.
new Promise로 객체를 생성할 때 인자로 콜백함수를 전달한다.
이 콜백함수는 두 개의 인자를 받는데, 첫번째 인자 (resolve)는 비동기가 성공했을 때 실행시킬 함수,
두번째 인자(reject)는 비동기가 실패했을 때 실행시킬 함수를 전달받는다.
const promise = (value) => new Promise((resolve, reject) => {
if(value === 'hi'){
resolve('success')
}else{
reject('failed')
}
});
promise('hi').then(console.log).catch(console.log)
//'success'
promise('no').then(console.log).catch(console.log)
//'failed'
그럼 이 resolve, reject 함수를 어떻게 전달하냐면
then의 콜백함수로 들어가는게 resolve,
catch의 콜백함수로 들어가는게 reject라고 보면 된다.
Promise 객체 내부는 대략 아래와 같이 생겼다고 보면 된다. 그래서 then과 catch에 접근할 때는 . 을 사용해 접근한 뒤,
접근한 메서드의 인자로 콜백함수를 전달하는 것이다.
Promise : {
then: (callback)=> {...},
catch: (callback)=> {...},
...
}
2. Promise의 상태
promise는 세가지 상태를 가진다.
- 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
new Promise로 전달하는 콜백함수 내부에서 resolve나 reject를 실행해주지 않는다면
promise의 상태는 계속 pending상태로 남는다. 때문에 resolve나 reject해줌으로써
성공했는지 실패했는지를 나타내주어야
then, catch를 통해 결과값을 받을 수 있다.
3. async-await 함수의 리턴된 값의 형태가 이상하다.
async함수는 기본적으로 Promise객체를 리턴하는 함수다. 때문에 아래와 같이 함수를 실행시키면
Promise {<fullfilled>: ...} 와 같은 값이 출력된다. 이런 프로미즈 객체를 사용하려는게 아니라
async function test(){
return 'test succeed'
}
console.log(test()) //Promise {<fulfilled>: 'test succeed'}
함수가 실행되고 난 뒤의 '값'을 받아 사용하고 싶다면
함수 내부에 await을 사용하거나, async함수를 실행하면서 then을 사용해줘야 한다.
// 방법 1
async function test(){
return 'test succeed'
}
console.log(test().then(console.log)) //'test succeed'
// 방법 2
async function test(){
return 'test succeed'
}
async function print(){
const data = await test()
const data2 = test()
console.log(data) //test succeed
console.log(data2) //Promise {<fulfilled>: 'test succeed'}
}
'개발' 카테고리의 다른 글
[Javascript] 빈 값을 표현할 때 undefined vs null 무엇을 써야 할까? (0) | 2023.12.31 |
---|---|
유용한 Javascript 교육 / 스터디 자료 (1) | 2023.05.19 |
[GPT] GPT4 사용 후기 + 6개월 사용 후기 (0) | 2023.03.27 |
[Javascript] 호이스팅이란? (feat. var, let, const, var가 똥인 이유) (0) | 2023.02.19 |
[Javascript] Scope란? 그리고 가비지컬렉터 (0) | 2023.02.19 |