오늘은 Promise
에 대해서 이야기를 나눠보려고 합니다.
요즘 들어서 기본 개념이 매우매우 부족하다는 생각을 하고 있습니다.. 🤦♂️
사실 Promise
에 대해서 공부하려고 하는 것도.. axios
라이브러리에 대해서 찾아보다가.. 이해가 잘 되지 않아서.. 찾아보게 되었습니다..
이러면서.. react-query
와 같은 라이브러리를 사용하겠다는 제 자신이 조금 부끄러워집니다.. 💩
그래도 이렇게 하나씩 배워가는거 아니겠나..! 라는 생각으로 정리해보려고 합니다.
Promise
Object
)Object
)state
와 Producer vs Consumer
2가지의 포인트를 가지고 개념을 이해하는 것이 좋다Promise 생성
const promise = new Promise((resolve, reject) => {
... // executor
})
Promise
는 위와 같은 문법으로 생성할 수 있습니다.
new Promise()
에 전달되는 함수는 executor
라는 이름을 가지고 있는데, (resolve, reject) => {}
와 같은 형태를 가지고 있습니다.
executor
함수는 new Promise
가 생성될 때 자동으로 실행됩니다.
executor의 인수
executor
는 resolve
, reject
2가지 인수를 받을 수 있습니다.
resolve
와 reject
는 자바스크립트에서 자체적으로 제공하는 콜백 함수입니다.
따로 선언할 필요 없이 executor
함수 안에 작성만 해주면 됩니다.
대신 executor
에서는 결과를 얻는 시점과 상관없이 상황에 따라 resolve
와 reject
콜백 함수 중 하나를 반드시 호출해야 합니다.
왜냐하면, executor
는 생성과 동시에 실행하게 되는데 executor
내부에서 로직을 처리하게 됩니다.
처리가 끝나면 바로 resolve
혹은 reject
콜백 함수를 호출하게 됩니다.
resolve, reject
executor
의 처리 성공 여부에 따라 실행되는 콜백함수resolve(value)
: 작업을 성공한 경우 결과(value
)와 함께 호출reject(error)
: 에러 발생 시 에러 객체를 나타내는 error
와 함께 호출Producer
const promise = new Promise((resolve, reject) => {
... // executor
setTimeout(() => {
// 성공
resolve('success!')
// 실패
reject(new Error('error!'))
}, 1000)
})
executor
의 로직(파일을 읽거나 네트워크 작업과 같은 작업)을 수행한 후 성공했을 때는 resolve()
를 통해서 받아온 값을 전달할 수 있습니다.
반대로 실패한 경우에는 reject()
와 Error
객체를 통해서 실패에 대한 값을 전달하게 됩니다.
Error
객체는 자바스크립트에서 제공하는 객체 중 하나입니다.
Consumer
new Promise
생성자가 반환하는 promise
객체then
, catch
, finally
를 이용해서 값을 받아올 수 있다Promise의 상태와 값
(Consumer의 상태
)new Promise
생성자가 반환하는 Promise
는 상태(status
)와 값(result
)을 가지게 됩니다.
상태는 pending
, fulfilled
, rejected
가 있고, 상태에 따라 값(result
)이 바뀌게 됩니다.
이러한 상태의 변경은 producer
에서 어떠한 함수를 호출하는가에 따라 달라지게 됩니다.
pending
promise₩
객체의 초기 상태 혹은 실행 중인 상태result
는 undefined
fulfilled
producer
에서 resolve
가 호출되면 나타나는 상태 (성공)result
는 resolve(value)
의 value
로 값이 바뀌게 된다.rejected
producer
에서 reject
가 호출되면 나타나는 상태 (실패)result
는 reject(error)
의 error
로 값이 바뀌게 된다.then
, catch
, finally
const promise = new Promise((resolve, reject) => {
resolve('success!')
reject(new Error('error!'))
})
then
resolve
콜백 함수를 통해서 전달된 값을 사용할 수 있다promise
도 전달할 수 있다.proimise
.then((value) => console.log(value)) // success!
value
라는 파라미터는 resolve
에서 전달하는 값을 받는 파라미터입니다.
그래서 value
라는 명칭을 고정해서 사용해야 하는 것은 아니고 적절한 명칭을 사용하면 됩니다.
catch
reject
콜백 함수를 통해서 전달된 에러에 대한 값을 사용할 수 있다promise
.catch((error) => console.log(error)) // Error: error! at ...
reject
콜백함수에서 전달한 error
에 대한 값을 catch
로 받지 않게 되면 Uncaught
에러로 표현되게 됩니다.
그래서 에러 핸들링을 위해서 catch
를 이용해서 실패에 대한 케이스를 처리해줘야 합니다.
finally
executor
의 성공과 실패 여부와 상관없이 무조건 호출되는 함수promise
.finally(() => console.log('finally!'))
만약 promise
에 대한 then
, catch
작업을 진행하고 싶다면 아래와 같이 Promise Chaining
형식으로 작성해야 합니다.
.then
에 대한 반환 값도 promise
이기 때문에, .catch
에 대한 처리를 진행할 수 있습니다.
promise
.then((value) => console.log(value))
.catch((error) => console.log(error))
const promise = new Promise((resolve, reject) => {
console.log("doing something...");
setTimeout(() => {
reject(new Error("no network"));
}, 1000);
});
promise
.then((value) => console.log(value))
.catch((error) => console.log(error))
.finally(() => console.log("finally"));
위와 같은 코드에서는 Error: no network at ...
와 같은 메시지와 finally
문자열이 콘솔에 찍히게 될 것입니다.
만약 catch
에 대한 처리를 해주지 않아도 Uncaught
에러와 함께 finally
는 작동하게 됩니다.
Promise Chaining and Error Handling
const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve("hen"), 1000);
});
const getEgg = (hen) =>
new Promise((resolve, reject) => {
// setTimeout(() => resolve(`${hen} => egg`), 1000);
setTimeout(() => reject(new Error(`error! ${hen} => egg`)));
});
const cook = (egg) =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => fried`), 1000);
});
getHen()
// .then((hen) => getEgg(hen))
// callback 함수를 전달할 때 받아오는 value를 다른 함수에서 바로 호출하는 경우에는 생략이 가능하다.
.then(getEgg)
// egg를 받아올 때 문제가 생긴다면 catch를 통해서 다른 것을 전달해줄 수 있다.
.catch(() => {
return "bread";
})
.then((egg) => cook(egg))
.then((meal) => console.log(meal))
.catch(console.log);
오늘은 Promise
에 대해서 알아보았습니다.
자바스크립트 책을 한 권 스터디하는 것도 좋을 것 같다는 생각이 듭니다.. 🤔
Producer
와 Consumer
의 개념을 사용한 것은 제가 참고한 유튜브에서 사용한 방식이기 때문에 공식적인 단어는 아닌 것으로 알고 있습니다.
해당 내용 참고하셔서 봐주시면 감사하겠습니다. 🙏