비동기 작업을 좀 더 편하게 처리 할 수 있도록 ES6에 도입된 기능
예전에 비동기 작업을 할 때 어떤 작업이 끝나고 나서 뭘 해야한다 했을 때 callback함수로 처리를 해줬어야 했는데, callback함수로 처리시 비동기 작업이 많아질 경우 코드가 쉽게 난잡해졌다.
그래서 promise
라는게 만들어졌다. 원래는 라이브러리로 존재 했지만, 편하다 보니 일반 JS스펙에 추가된 기능
비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 promise를 사용하여 결과를 반환. 그러나 비동기 함수를 사용하는 코드의 구문과 구조는, 표준 동기 함수를 사용하는 것과 많이 비슷하다.
즉, promise
의 resolve
와 reject
, .then()
을 우리가 익숙산 동기 함수를 작성하는 것처럼 만들어주기 위해 추가된 문법이라 생각하면 된다.
이 과정에서 평상시 사용하던 것처럼 try catch문을 사용할 수 있는 것, 그렇지만 이렇게 만들어진 async function도 promise를 반환하므로, promise를 이용해 만든 함수처럼 사용할 수 있다.
function increaseAndPrint(n, callback){
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if(callback){
callback(increased)
}
}, 1000)
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n =>
increaseAndPrint(n, n => {
console.log('작업 끝!');
})
)
})
})
});
동작의 흐름
increaseAndPrint
함수에선 첫번째 파라미터 n에 숫자를 받아오고 두번째 파라미터에선 n에 1을 던한 결과 값을 인자로 넣어서 호출 할 함수를 받아온다.increaseAndPrint
가 호출되고 나서 또 다시 자기 자신을 호출하기 위해 연달아서 increaseAndPrint
가 작성 됐다.increaseAndPrint
호출 -> n
에 1
더함 -> 더한 값을 가지고 다시 increaseAndPrint
호출>이 값이 5가 될때까지 반복promise
는 성공할 수 있고, 실패할 수도 있다. 성공 할 때는 resolve
, 실패할 때는 reject
호출.then
으로 promise
가 끝나고 할 작업을 설정성공시(resolve)
const myPromise = new Promise((resolve, reject) => {
//구현...
setTimeout(() => {
resolve('result');
}, 1000)
});
myPromise.then(result => {
console.log(result);
});
실패시 - 에러를 잡을땐 .catch
const myPromise = new Promise((resolve, reject) => {
//구현...
setTimeout(() => {
reject(new Error());
}, 1000);
});
myPromise.then(result => {
console.log(result)
}).catch(e => {
console.error(e);
})
- promise의 catch 함수는 앞서 만든 promise에서 reject한 값을 받아 올때 사용한다.
여기서 e는 reject에 인자로 넣어준 값이다.
- console.error 는 console.log와 달리 빨간색으로 나온다. 콘솔에서 에러가 난 것을 더욱 쉽게 알 수 있게 해준다.
function increaseAndPrint(n){
return new Promise((resolve, reject) => {
setTimeout(() => {
const value = n + 1;
if(value === 5) {
const error = new Error;
error.name = 'ValueIsFiveError';
reject(error);
return;
}
console.log(value);
resolve(value);
}, 1000);
});
}
increaseAndPrint(0).then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e => {
console.error(e);
})
increaseAndPrint
의 파라미터에 콜백이 사라진 이유
- 콜백을 없앤 이유는 우리가 콜백을 통해서 그 다음 처리 할 작업을 넣어주지 않고 promise
의 then
을 통해서 하기 위함
error를 따로 만든 이유
- error
에 ValueIsFiveError
라는 이름을 설정 해주기 위함
- n + 1
값은 promise
의 결과값으로 n + 1
를 설정한다는 뜻
then
- increaseAndPrint(0)
의 결과 1을 .then의 파라미터 n으로 받아와서 다시 increaseAndPrint
를 호출
catch 왜 했는지
- catch를 한 이유는 에러가 발생했을 때 특정 작업을 하기 위함
- catch를 안했을 땐 "Uncaught (in promise) ValueIsFiveError" - ValueIsFiveError
가 잡히지 않았다.
- catch를 했을 땐 ValueIsFiveError
라고 나타남
- 즉, 콘솔에 출력되는 결과가 다르기 때문
함수를 넣어주기
- .then에 인자로 넣어주어야 하는 것은 함수다.
- .then에서 새로 함수를 선언하지 않고 increaseAndPrint
를 넣어주면 앞서 호출한 increaseAndPrint
의 결과값을 다시 increaseAndPrint
의 인자로 넣어서 호출하게 된다.
- 파라미터를 여러개 받아와야 하는 경우에는 함수를 새로 선언해야 한다.
UnhandledPromiseRejectionWarning
이라는 경고 메세지가 뜸. 브라우저에서는 Uncaught (in promise) ValueIsFiveError
라는 오류가 뜸이 글은 패스트캠퍼스 '프론트엔드(React)올인원패키지Online'을 수강하며 정리한 노트입니다.
https://fastcampus.co.kr/search?keyword=%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C