일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 스텍
- AtoZ0403
- 삼성
- 배열
- 코테
- javascript
- js
- NestJS
- 프로그래머스
- 카카오
- 백준
- mybatis
- 자바
- 그리디알고리즘
- 자료구조
- 알고리즘
- 인프런
- 자바스크립트
- java
- 콜백지옥
- 삼성소프트웨어아카데미
- 코딩
- 정렬
- stack
- 코테준비
- SWEA
- spring
- array
- 코딩테스트
- 중간 평균값 구하기
- Today
- Total
개발에 AtoZ까지
[ES6][JS] Javascript 비동기 처리(Promise) 2탄 본문
◆목표
Promise 등장 배경 및 정의
Promise 사용법
콜백 지옥에 대한 Promise 해결법
Promise의 기타 문법
1. Promise 등장 배경 및 정의
- 콜백함수의 단점인 콜백 지옥을 해결하기 위해 등장
- 비동기적 처리의 근본적인 문제점이였던 서버에서 데이터를 받아오기 전에 화면에 데이터를 표시하려고 할 때 발생하는 오류를 해결하기 위해 등장
- ES6에서 부터 추가된 문법으로 비동기 처리를 위해 기존에 있던 단점들을 보완하기 위해 사용됨
2. Promise 사용법
- promise 객체를 생성
- promise 객체는 executor라는 함수가 내부적으로 자동적으로 실행되는데 executor 함수에서는 resolve와 reject라는 두개의 함수를 인자로 받아서 비동기 처리 함수를 실행함
- executor를 통해 비동기 처리 함수를 실행 완료 후에 해당 작업이 성공하면 resolve 함수를 실패하면 reject 함수를 호출한다.
- resolve, reject 함수 정의는 then() 메소드를 사용해서 정의해주면 된다.
//Promise 객체 생성
const promise_test = new Promise((resolve, reject) => {
//비동기 작업 수행
setTimeout(() => {
let num = 10;
if (num >= 9) {
resolve("성공: " + num);
} else {
reject("실패: " + num);
}
}, 1000);
});
//promise 객체를 실행시켜줄 then 메소드 사용
promise_test.then((str)=>{
//성공했을때 실행, str 매개변수는 promise 실행시 넘오는 값이라고 생각하면됨
console.log(str);
},(str)=>{
//실패했을때 실행
console.log(str);
}
);
3. 콜백지옥에 대한 Promise 해결법
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
let num = 1;
if (num == 1) {
resolve(num);
} else {
reject("error");
}
}, 500);
});
//실행 순서에 맞출 필요가 있을 경우, then을 이어서 작성해줌(콜백지옥에서 해방됨)
promise
.then(
(num) => {
console.log(num);
},
(err) => {
console.log(err);
}
)
.then(() => {
console.log("close");
});
4. Promise의 기타 문법
1) catch 메서드
- 실행 중, 예외 상황(오류)을 처리함
- then 메서드에 failureCallback 함수를 정의하지 않은 상황에서 실패한 경우에도 catch 메서드가 호출됨
- 보통 catch문을 chaining(아래 참고)의 맨 마지막에 추가해서, 전체 코드의 에러 케이스를 핸들링함
const asyn = new Promise((resolve, reject) => {
setTimeout(() => {
let num = 2;
if (num == 1) {
resolve(num);
}
//실패했을경우 에러를 발생시킴
reject(new Error("에러가 발생함"));
}, 500);
});
asyn
.then((num) => {
console.log(num);
})
//에러가 발생해서 catch 메소드로 들어옴
.catch((error) => {
console.log(error);
});
Tip) throw 메서드
- 사용자 정의 예외를 던질 때 사용
- catch 블록이 있으면 catch 블록으로 전달되고, 그렇지 않으면 프로그램을 종료함
- 보통 다음과 같은 구문으로 사용됨(Error 클래스의 객체를 만들어서, 전달함)
const asyn = new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 500);
});
asyn
.then(() => {
console.log("성공");
//강제적으로 에러를 호출함
throw new Error("에러가 발생함");
})
//에러가 발생해서 catch 메소드로 들어옴
.catch((error) => {
console.log(error);
});
2) chaining
- then 메서드를 연결해서, 순차적으로 실행되야할 코드를 연결할 수 있음
- then과 catch 메서드로 함께 연결해서 실행 가능함
const asyn = new Promise((resolve, reject) => {
console.log("start");
resolve();
});
asyn
.then(() => {
console.log("1");
})
.then(() => {
console.log("2");
throw new Error("error");
})
.catch((err) => {
console.log(err);
});
const asyn = new Promise((resolve, reject) => {
console.log("start");
resolve();
});
asyn
.then(() => {
console.log("1");
throw new Error("error");
})
.catch((err) => {
console.log(err);
})
.then(() => {
console.log("2");
});
3) chaining과 return
-상위 chaining에서 return을 하면 다음 chaining에서 매개변수로 받아서 재사용이 가능함
const asyn = new Promise((resolve, reject) => {
console.log("start");
resolve(1);
});
asyn
.then((num) => {
console.log(num);
return num;
})
.then((num) => {
console.log(num + 1);
throw new Error("error");
})
.catch((err) => {
console.log(err);
})
4) finally 메서드
- promise의 결과값이 resolve(성공)든 reject(실패)든 무조건 실행하게 하는 메서드
const asyn = new Promise((resolve, reject) => {
console.log("start");
let flag = true;
if (flag) {
resolve(flag);
}
});
asyn
.then(
(flag) => {
console.log("성공: " + flag);
},
() => {
console.log("실패");
}
)
.finally(() => {
console.log("finally 호출");
});
const asyn = new Promise((resolve, reject) => {
console.log("start");
let flag = true;
if (flag) {
resolve(flag);
}
});
asyn
.then(
(flag) => {
console.log("성공: " + flag);
throw new Error("에러발생");
},
() => {
console.log("실패");
}
)
//finally은 finally 메소드 나오기 전까지의 then만 신경씀,
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("finally 호출");
})
.then(() => {
console.log("catch문 다음 then");
});
5) Promise.all 메서드
- 동기화 처리할 Promise를 묶어서 한 번에 실행
- 묶은 Promise가 모두 실행된 후에, then 구문을 실행함
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p1");
}, 500);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2");
}, 100);
});
Promise.all([p1, p2]).then((data) => {
console.log(data);
});
6) Promise.race 메서드
- 동기화 처리할 Promise를 묶어 놓은 것 중 1개라도 먼저 끝났을 때 then 구문을 실행함
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p1");
}, 500);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2");
}, 100);
});
Promise.race([p1, p2]).then((data) => {
console.log(data);
});