Promise (then & catch) JavaScript
이전 포스트에서 설명한 비동기적 처리의 개념을 공부하고 Promise에 대해 공부하는 것이 더 좋은 방향이라고 생각합니다.
이전 포스트를 아직 읽어보시지 않으셨다면 읽고 보시는 것을 추천드려요!
[JavaScript] - 동기적, 비동기적 처리, 콜백 함수 - JavaScript
Promise는 무엇이고 왜 사용하나요?
Promise 문법을 사용하는 이유는 어떠한 작업을 비동기적으로 처리할 때 그 작업이 성공했는지 실패했는지를 쉽게 정리할 수 있도록 해줍니다. (즉 표준화된 처리를 가능하도록해줍니다)
Fetch 함수는 비동기적 처리방식을 이용합니다. 또한 Promise를 반환하기 때문에 이를 이용하여 정리해보겠습니다.
fetch 함수
fetch('<http://example.com/movies.json>')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
fetch의 사용 방법입니다. 하지만 promise에 대해 조금 더 자세히 공부하기 위해 다른 방식의 코드를 사용하여 내용을 들여다보겠습니다.
fetch 함수를 통해 return하는 값 확인
let fetched = fetch('<http://example.com/movies.json>');
console.log('fetched', fetched);
fetch 함수를 통해 얻는 값은 promise 형태로 리턴해줍니다.
이렇게 리턴 값이 promise인 경우는 비동기적 함수일 가능성이 아주 높고 then과 catch라는 두 개의 함수를 이용할 수 있습니다.
이 then과 catch는 콜백 함수를 받습니다.
then과 catch 함수
- then 함수는 promise 값을 성공적으로 받았을 때 실행되는 코드이고
- catch 함수는 값을 받아오는 것을 실패했을 때 에러 출력해주는 코드입니다.
then과 catch 사용
let fetched = fetch('<http://example.com/movies.json>');
console.log('fetched', fetched);
fetched.then(function(result) {
console.log('result', result);
});
fetched.catch(function(reason) {
console.log('reason', reason);
})
then을 사용해 result를 출력하면 아래와 같은 내용을 확인할 수 있습니다.
Response라는 객체의 값을 리턴 받은 것입니다.
실패한다면 reason이라는 텍스트와 에러의 이유를 출력해줍니다.
위 코드를 정리하여 데이터를 뽑아보겠습니다.
fetch 함수가 Promise를 바로 return하기 때문에 깔끔한 코드 작성 가능함.
fetch('<http://example.com/movies.json>')
.then(function(result) {
console.log('result', result.json());
})
.catch(function(reason) {
console.log('reason', reason);
})
위와 같이 코드를 작성하면 또 promise를 리턴합니다. 이유는 다른 분께서 작성해주신 내용을 가져왔습니다.
이유는 아직 데이터를 다 받지 않은 상태여서 그렇습니다.(header만 도착하고 body가 오지 않음) 그래서 다시 체이닝을 통해 작업하는 것이죠. (데이터가 다 도착한 이후에) 그것이 싫다면 전체에 await을 걸어서 기다린 이후에 json을 입히면 됩니다.
promise를 리턴한다면 then과 catch를 또 사용할 수 있습니다. 데이터를 뽑아보면
then 안에 then & Nested Promise
fetch('<http://example.com/movies.json>')
.then(function(result) {
result.json().then(function(data) {
console.log('data', data)
});
})
.catch(function(reason) {
console.log('reason', reason);
})
위와 같이 데이터를 가져오는 방식을 Nested Promise 방식이라고 합니다.
다른 방식으로 처음에 본 예제는 훨씬 더 간단해 보이는데 그 방식을 이용하면
promise chaining
fetch('<http://example.com/movies.json>')
.then(function(result) {
return result.json();
})
.catch(function(reason) {
console.log('reason', reason);
})
.then(function(data) {
console.log('data', data)
})
이와 같은 방식은 promise chaining 방식이라고 부릅니다. 훨씬 깔끔해여서 더 자주 쓰이는 방식입니다.
위와 같이 Promise는 then과 catch를 통해 또 다른 Promise를 반환한다는 것을 알아보았습니다.
then과 catch 말고도 비교적 최신 함수 finally라는 함수도 있습니다.
finally 함수
이 finally 함수는 성공하든 실패하던 콜백 함수를 실행하여 줍니다. 예시를 보면
finally 함수 사용법
fetch('<http://example.com/movies.json>')
.then(function(result) {
return result.json();
})
.catch(function(reason) {
console.log('reason', reason);
})
.finally(() => {
console.log('finally')
})
//fetch 실패시 에러 출력 다음으로 'finally'를 출력해줌, 성공시에도 finally 코드 실행
이러한 then과 catch는 Consumer로 칭해집니다. 그렇다면 Producer는 무엇일까요.
Producer로는 나만의 promise를 만들 수 있습니다.
Producer (내가 만드는 Promise)
let task1 = new Promise(function(resolve, reject){
resolve('resolved ok!');
reject('failed!');
});
task1
.then((data) => console.log('data', data))
.catch((error) => console.log('error', error))
변수로 지정하여 새로운 promise 객체를 생성하고 여기서 resolve와 reject 파라미터는 관습적으로 이렇게 사용되고 성공했을 때와 실패했을 때에 실행될 함수를 정의해주면 됩니다.
함수로 Promise 생성
function task1() {
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve('task1 ok!');
}, 2000)
});
}
function task2() {
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve('task2 ok!');
}, 2000)
});
}
위의 코드는 함수로 프로미스를 생성한 방식이다 재사용성이 더 높아 사용하기 편합니다.
함수로 만든 Promise, Nested 방식으로 사용
// Nested promise
task1().then((data) => {
console.log('data1', data);
task2().then((data) => {
console.log('data2', data);
})
});
Nested 방식으로 then안에 then을 작성하는 방식이다.
함수로 만든 Promise, Chaining 방식으로 사용
// promise chaining
task1()
.then((data) => {
console.log('data1', data);
return task2();
})
.catch((error) => {
console.log('error', error);
return Promise.reject(); // 다음 코드가 아예 실행되지 않도록 하고 싶을 때 사용
})
.then((data) => {
console.log('data2', data);
})
Chaining방식으로 선호되는 방식입니다.. return을 잘 활용하여 깔끔한 코드를 작성할 수 있습니다.
then, catch 그리고 Producer로 새로운 Promise를 생성하여 resolve, reject를 잘 활용하면 콜백지옥도 벗어날 수 있다.
물론 앞의 then에서 오류로 인해 실패하면 뒤의 then들은 실행되지 않는다는 점을 유의해야 합니다.
다음 포스트로는 async, await에 대해 포스트 할 예정입니다.
참고자료 생활코딩 promise(1) , promise(2)
'JavaScript' 카테고리의 다른 글
async & await - JavaScript (0) | 2022.04.15 |
---|---|
동기적, 비동기적 처리, 콜백 함수 - JavaScript (0) | 2022.04.13 |
쿠키, 로컬스토리지와 세션스토리지 - JavaScript (0) | 2022.04.04 |
Webpack과 Babel - JavaScript (0) | 2022.03.30 |
클래스(Class) - JavaScript (0) | 2022.02.28 |