먼저,
자바스크립트는 싱글 쓰레드로 동작하는 언어입니다. (메인 쓰레드 하나와 콜스택 하나로 구성되어 있어요!)
그리고 비동기 작업을 동시에 할 수 있어요.
오잉?🤢 1번에 1개의 작업만 할 수 있는데, 어떻게 동시 실행을 할까요?
→ 자바스크립트는 코어 엔진만 가지고 돌아가지 않아요!
실행환경(런타임)의 도움을 받아 동시 실행을 합니다.
(WebAPI(dom, ajax, setTimeout...), Task Queue, Event Loop 등과 함께 동작합니다.)
콜백 헬
꼬리에 꼬리를 무는 비동기 처리가 늘어나면 호출이 계속 중첩되고, 코드가 깊어지고, 관리는 어려워집니다. 이런 깊은 중첩을 콜백 헬이나 멸망의 피라미드라고 부릅니다.
function async1('a', function (err, async2){
if(err){
errHandler(err);
}else{
...
async2('b', function (err, async3){
...
}){
...
}
}
});
- 이런 콜백 헬이 발생하는 이유?
- 비동기 처리 시에는 실행 완료를 기다리지 않고 바로 다음 작업을 실행해요.
- 즉, 순서대로 코드를 쭉 적는다고 우리가 원하는 순서로 작업이 이뤄지지 않습니다.
- 비동기 처리 함수 내에서 처리 결과를 반환하는 걸로는 원하는 동작을 하지 않으니, 콜백 함수를 사용해 원하는 동작을 하게 하려고 콜백 함수를 씁니다.
- 이 콜백 함수 내에서 또 다른 비동기 작업이 필요할 경우 위와 같은 중첩이 생기면서 콜백 헬이 탄생하죠. 😢
💡 비동기 연산이 종료된 이후 결과를 알기 위해 사용하는 객체입니다!
프라미스를 쓰면 비동기 메서드를 마치 동기 메서드처럼 값을 반환할 수 있어요.
전통적인 콜백 패턴으로 인한 콜백 헬 때문에 ES6에서 도입한 또다른 비동기 처리 패턴입니다.
**비동기 처리 시점을 좀 더 명확하게 표현할 수 있어요!**
1. 프라미스 생성
- 프라미스는 Promise 생성자 함수(new 키워드 기억하시죠!)를 통해 생성합니다.
- 비동기 작업을 수행할 콜백 함수를 인자로 전달받아서 사용합니다.
// 프라미스 객체를 만듭니다.
// 인자로는 (resolve, reject) => {} 이런 excutor 실행자(혹은 실행 함수라고 불러요.)를 받아요.
// 이 실행자는 비동기 작업이 끝나면 바로 두 가지 콜백 중 하나를 실행합니다.
// resolve: 작업이 성공한 경우 호출할 콜백
// reject: 작업이 실패한 경우 호출할 콜백
const promise = new Promise((resolve, reject) => {
if(...){
...
resolve("성공!");
}else{
...
reject("실패!");
}
});
// 프라미스를 하나 만들어 봅시다!
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000);
});
// resolve
promise.then(result => {
console.log(result); // 완료!가 콘솔에 찍힐거예요.
}, error => {
console.log(error); // 실행되지 않습니다.
});
// 프라미스를 하나 만들어 봅시다!
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("오류!")), 1000);
});
// reject
promise.then(result => {
console.log(result); // 실행되지 않습니다.
}, error => {
console.log(error); // Error: 오류!가 찍힐거예요.
});
// 프라미스를 하나 만들어 봅시다!
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("오류!"), 1000);
});
promise.catch((error) => {console.log(error};);