자바스크립트에서의 동기 처리
자바스크립트 코드는 한번에 한줄 씩 차례로, 동기식으로 처리됩니다(콜스택에서 순차적으로 실행).
한 작업이 실행되는 동안 다른 작업은 멈춘 상태로 차례를 기다린다는 것입니다.
console.log(1);
console.log(2);
console.log(3);
// 출력 순서: 1 -> 2 -> 3
// 코드가 적힌 순서(위에서 아래)대로 찍힙니다.
자바스크립트에서의 비동기 처리
특정 코드(setTimeout, addEventListener, ajax)들은 기다리지 않고 바로 다음 코드를 실행합니다.
다음 예시에서는 1을 출력한 후 1초 뒤에 2를 출력해 보겠습니다.
console.log(1);
setTimeout(() => {}, 1000);
console.log(2);
1초 뒤가 아니라, 1이 출력되자마자 2가 바로 출력됩니다.
setTimeout은 비동기로 처리되는 함수이므로 WebAPI로 넘어가고 바로 console.log(2)가 출력되기 때문입니다.
그래서 다음과 같이 수정하면 1초 뒤에 2를 출력하게 할 수 있습니다
console.log(1);
setTimeout(() => {
console.log(2);
}, 1000);
만약 setTimeout이 비동기가 아니었다면, web브라우저는 1초동안 setTimeOut을 실행하느라 아무 동작도 할 수 없게 됩니다.
이렇게 코드를 읽고 동작까지 오래 걸리는 경우를 위해 비동기 처리가 필요합니다.
프로미스
자바스크립트 비동기 처리에 사용되는 객체입니다.
Promise를 생성하는 시점에 콜백 함수가 바로 실행되며, 필요할 때 Promise를 꺼내 쓸 수 있습니다.
*생성시점과 사용시점을 분리할 수 있습니다.
// 생성시점
const promise = new Promise((resolve) => {
resolve('ok')
});
//사용 시점
promise
.then((res) => {
console.log(res);
})
프로미스의 상태는 다음과 같습니다.
- Pending(대기): 초기 상태
- Fulfilled(이행): 성공적으로 완료된 상태
- Rejected(실패): 실패 상태
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (true) resolve("success");
else reject("fail");
}, 1000);
});
console.log(promise); // 대기 (promise 생성 되기 전에 출력 되었을 경우)
promise
.then((res) => {
console.log(res); // 이행
})
.catch((err) => {
console.log(err); // 실패
});
.finally(() => {
console.log("무조건 실행") // 이행 여부 관계 없이 실행
});
Async / Await
ES8 문법으로, Promise, then을 조금더 쉽게 만들어줍니다.
async 키워드를 쓰면 Promise 오브젝트가 생성됩니다.
const promiseObj = new Promise((resolve) => {
resolve('성공');
});
const asyncFn = async () => {
// resolve를 return으로 표시합니다.
return '성공';
};
// promiseObj과 asyncFn()는 동일하게 프로미스 객체를 만들어줍니다.
// 두 프로미스 모두 then으로 resolve('성공')를 가져올 수 있습니다.
promiseObj.then((res) => console.log(res)) // 성공
asyncFn().then((res) => console.log(res)) // 성공
await으로 then을 대신할 수 있습니다.
*다만, await은 async 함수 안에서만 동작하므로, 상황에 따라, 취향에 따라 선택하면 됩니다.
const calc = async () => {
const add = async () => {
return "성공";
};
const result = await add();
// Promise 객체인 add()가 이행될 때까지 기다렸다가 result를 출력합니다.
console.log(result);
};
calc();
상태처리는 다음과 같이 합니다.
const calc = async () => {
const add = async () => {
const a = 2;
if (a === 1) return "성공";
else return Promise.reject("실패");
};
try {
const result = await add();
console.log(result); // fulfilled
} catch (e) {
console.log(e); // rejected
} finally {
console.log("끝");
}
};
calc();
[참고자료]
'Javascript' 카테고리의 다른 글
| 함수형프로그래밍 (0) | 2024.04.11 |
|---|---|
| 번들러 (0) | 2024.04.11 |
| 프로토타입 (1) | 2024.04.11 |
| 원시 / 참조 타입 (0) | 2024.04.11 |
| 깊은 복사와 얕은 복사 (0) | 2024.04.11 |