일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 집합_SET
- NestedFor
- 제네릭
- Java
- 인터페이스
- abstract
- GRANT VIEW
- 한국건설관리시스템
- 대덕인재개발원
- oracle
- 어윈 사용법
- 오라클
- EnhancedFor
- 예외처리
- exception
- 생성자오버로드
- 예외미루기
- 사용자예외클래스생성
- 다형성
- 컬렉션 타입
- 자동차수리시스템
- 추상메서드
- 참조형변수
- 객체 비교
- 컬렉션프레임워크
- 메소드오버로딩
- 환경설정
- 정수형타입
- cursor문
- 자바
- Today
- Total
거니의 velog
(17) 자바스크립트에서 비동기 처리 다루기 2 본문
1. Promise
* 프로미스는 비동기 작업을 조금 더 편하게 처리 할 수 있도록 ES6 에 도입된 기능이다. 이전에는 비동기 작업을 처리 할 때에는 콜백 함수로 처리를 해야 했었는데, 콜백 함수로 처리를 하게 된다면 비동기 작업이 많아질 경우 코드가 쉽게 난잡해지게 되었다.
* 한번 숫자 n 을 파라미터로 받아와서 다섯번에 걸쳐 1초마다 1씩 더해서 출력하는 작업을 setTimeout 으로 구현해보자.
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('끝!');
});
});
});
});
});
* 코드 읽기가 복잡해지고 있다. 이런 식의 코드를 우리는 Callback Hell (콜백지옥) 이라고 부른다.
* 비동기적으로 처리해야 하는 일이 많아질수록, 코드의 깊이가 계속 깊어지는 현상이 있는데, Promise 를 사용하면 이렇게 코드의 깊이가 깊어지는 현상을 방지 할 수 있다.
(1) Promise 만들기
* Promise 는 다음과 같이 만든다.
const myPromise = new Promise((resolve, reject) => {
// 구현..
})
* Promise 는 성공 할 수도 있고, 실패 할 수도 있다. 성공 할 때에는 resolve 를 호출해주면 되고, 실패할 때에는 reject 를 호출해주면 된다. 지금 당장은 실패하는 상황은 고려하지 않고, 1초 뒤에 성공시키는 상황에 대해서만 구현을 해보자.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
myPromise.then(n => {
console.log(n);
});
* resolve 를 호출 할 때 특정 값을 파라미터로 넣어주면, 이 값을 작업이 끝나고 나서 사용 할 수 있다. 작업이 끝나고 나서 또 다른 작업을 해야 할 때에는 Promise 뒤에 .then(...) 을 붙여서 사용하면 된다.
* 이번에는, 1초뒤에 실패되게끔 해보자.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error());
}, 1000);
});
myPromise
.then(n => {
console.log(n);
})
.catch(error => {
console.log(error);
});
* 실패하는 상황에서는 reject 를 사용하고, .catch 를 통하여 실패했을시 수행 할 작업을 설정 할 수 있다.
* 이제, Promise 를 만드는 함수를 작성해보자.
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((n) => {
console.log('result: ', n);
})
* 여기까지만 보면, 결국 함수를 전달하는건데, 뭐가 다르지 싶을수도 있다. 하지만, Promise 의 속성 중에는, 만약 then 내부에 넣은 함수에서 또 Promise 를 리턴하게 된다면, 연달아서 사용 할 수 있다. 다음과 같이 말이다.
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(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.then(n => {
return increaseAndPrint(n);
})
.catch(e => {
console.error(e);
});
* 위 코드를 이렇게 정리할 수 있다.
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);
});
* Promise 를 사용하면, 비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않게 된다.
* 하지만, 이것도 불편한 점이 있긴 하다. 에러를 잡을 때 몇번째에서 발생했는지 알아내기도 어렵고 특정 조건에 따라 분기를 나누는 작업도 어렵고, 특정 값을 공유해가면서 작업을 처리하기도 까다롭다.
* 다음에 배울 async/await 을 사용하면, 이러한 문제점을 깔끔하게 해결 할 수 있다.
'JS_Modern JS(ES6 이후)' 카테고리의 다른 글
(19) HTML 과 JavaScript 연동하기 1 (0) | 2023.11.06 |
---|---|
(18) 자바스크립트에서 비동기 처리 다루기 3 (0) | 2023.11.06 |
(16) 자바스크립트에서 비동기 처리 다루기 1 (0) | 2023.11.06 |
(15) 알고 있으면 유용한 자바스크립트 문법 5 (0) | 2023.11.06 |
(14) 알고 있으면 유용한 자바스크립트 문법 4 (0) | 2023.11.06 |