Synchronous(동기) | 코드가 순서대로 실행된다. |
---|---|
Asynchronous(비동기) | 실행되는 데 순서가 없다. |
자바스크립트에서는 함수가 여러 번 호출될 때 순서대로 실행되지 않는다. 시간이 오래 걸리는 작업이 끝날 때까지 기다리는 것은 매우 비효율적이기 때문에 빨리 끝낼 수 있는 것부터 먼저 끝낸다. 이것이 🙈비동기 처리🙉이다.
function asyncBlackBeanTimer(seconds) {
console.log("짜장면이 고객에게 배달");
setTimeout(function () {
console.log("고객 식사 완료"); ---> 콜백 함수
}, seconds * 1000);
console.log("배달부 떠남");
}
asyncBlackBeanTimer(2);
동기 프로그래밍을 하면 "짜장면이 고객에게 배달 ➡️ 고객 식사 완료 ➡️ 배달부 떠남"이 된다. 배달부는 고객이 짜장면을 다 먹을 때까지 기다리는 것이다. 이건 매우 비효율적이다. 차라리 이때 다른 배달 한 건 더 뛰는 게 낫다.
비동기 코드가 끝나면 내부에 있는 함수를 호출한다. 끝나면 불러줘! == 콜백 함수
비동기 코드가 끝난 후 콜백 함수가 호출되면, 이 콜백 함수는 task queue에 올라간다. 이벤트 루프가 task queue에 있는 콜백 함수를 순서대로 실행한다.
짜장면을 만드는 순서를 확인해보자.
function asyncBlackBeanTimer(seconds) {
setTimeout(function () {
console.log("야채 썰기");
setTimeout(function () {
console.log("춘장 만들기");
setTimeout(function () {
console.log("고기 볶기");
setTimeout(function () {
console.log("완성!");
}, seconds * 1000);
}, seconds * 1000);
}, seconds * 1000);
}, seconds * 1000);
}
asyncBlackBeanTimer(2);
"야채 썰기"가 끝나면 "춘장 만들기"를 호출한다. 이렇게 순서대로 동작하지만, 코드를 작성할 때도 헷갈리고 코드가 길어지면 무슨 동작을 하는 건지 쉽게 파악할 수 없다. 이런 코드는 ❌
콜백 지옥을 해결할 수 있는 방법으로 promise
가 있다. 콜백 지옥보다는 쉽게 이해할 수 있다.
new Promise()
로 프로미스를 생성한 후, 종료될 때까지 3가지 상태를 갖는다.
new Promise()
를 호출하면 대기 상태가 된다. new promise()
를 호출할 때 콜백 함수를 선언할 수 있다. 콜백 함수의 인자는 resolve
와 reject
가 있다.
resolve()
를 실행하면 이행된다. then()
으로 resolve(여기 있는 값 == 처리 결과 값)
을 받아올 수 있다.
reject()
를 실행하면 실패한다. catch()
로 reject(여기 있는 값 == 실패한 이유)
를 받아올 수 있다.
...
const done = (seconds) => {
return new Promise((resolve) => setTimeout(() => {
resolve("완성!");
}, seconds * 1000));
}
function asyncBlackBeanTimer(seconds) {
cutting(1)
.then(
(text) => {
console.log(text);
return makeSource(1);
})
.then(
(text) => {
console.log(text);
return roasting(2);
})
.then(
(text) => {
console.log(text);
return done(1);
})
.then(
(text) => {
console.log(text);
})
}
asyncBlackBeanTimer(1);
promise
보다 조금 더 이해하기 쉽게 표현하기 위해서는 async/await
를 사용한다. 비동기 함수를 동기 함수처럼 호출할 수 있다.
에러를 잡기 위해서는 try catch
를 사용하면 된다.
async function asyncBlackBeanTimer(seconds) {
const result = await cutting(seconds); --> await 어어어어어어 wait!
console.log(result);
const result2 = await makeSource(seconds);
console.log(result2);
const result3 = await roasting(seconds);
console.log(result3);
const result4 = await done(seconds);
console.log(result4);
}
참고 자료