티니핑 캐릭터들로 무거운 포스팅을 환기하고 싶
이전에 비동기 처리 방식에 대한 질문이 왔었고 그 때 당시에는 어물쩡하게 답했지만 제대로 알 필요가 있다고 생각하여 포스팅을 오랜만에 하게 되었다.
해당 글은 1/5에 노션으로 작성한 걸 옮긴 것입니다.
함수의 호출을 스택방식으로 기록하는 자료구조, 한 번에 하나의 Task만 처리 가능
Promise, async/await와 같은 비동기 호출의 Callback함수들은 해당 스택에 담기게 된다.
Eventloop는 현재 실행중인 Task가 있는지, 큐들에 적재된 Task가 있는지 주기적으로 확인하고 만약 실행중인 Task가 콜 스택에 없다면 큐에서 꺼내와 콜 스택에 올리고 실행시키는 역할을 한다.
즉, Promise를 반환하면 비동기로 실행된다고 해서 병렬로 실행된다는 아니라는 것
Promise의 then
, catch
, finally
로 전달되는 Callback 함수가 비동기로 실행되는 것!
setTimeout
으로, 후순위로 밀려나고 callback함수를 사용해서 동기적으로 코드가 작성하는 것처럼 보여줄 수 있다.// 코드 실행이 어떻게 될까요? 🙃
function processOrder(orderNumber) {
if (!orderNumber) {
return console.log("주문번호가 없습니다");
}
console.log(`주문 ${orderNumber}번 처리중...`);
startCooking();
}
function checkInventory(item, callback) {
console.log("재고 확인중...");
console.log(`${item} 찾는중...`);
setTimeout(() => {
const stock = {
'파스타': { quantity: 5, orderNum: 'A123' },
'피자': { quantity: 0, orderNum: 'B456' },
'샐러드': { quantity: 3, orderNum: 'C789' }
};
callback(stock[item]?.orderNum);
}, 2000);
}
function startCooking() {
setTimeout(() => {
console.log("조리 시작!");
setTimeout(() => {
console.log("완성되었습니다!");
}, 1000);
}, 1500);
}
function orderFood(menu, callback) {
console.log(`${menu} 주문이 들어왔습니다`);
checkInventory(menu, callback);
}
orderFood('파스타', processOrder);
// 실행 결과
// "파스타 주문이 들어왔습니다"
// "재고 확인중..."
// "파스타 찾는중..."
// (2초 후) "주문 A123번 처리중..."
// (1.5초 후)"조리 시작!"
// (1초 후)"완성되었습니다!"
then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환 (약간 아래와 같은 방식으로)
function getData() {
return new Promise({
// ...
});
}
// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
.then(function(data) {
// ...
})
.then(function() {
// ...
})
.then(function() {
// ...
});
Promise.all
async function concat(){
const a = await one();
const b = await two();
return a+b;
}
Promise.all
function concat(){
return Promise.all([one(),two()]).then(res=>
res[0]+res[1]);
}
concat().then(console.log);
사용은 Promise.all
의 인자로 병렬로 실행시킬 함수들을 배열로 넣어주면 된다.
웹 코드를 작성하는데 필요한 작업들을 모아둔 API들
브라우저나 nodeJS와 같은 런타임에 탑재되어 있다.
여기에 있는 API는 대표적으로 fetch, setTimeout, setInterval
등이 있다.
실행 방식을 제대로 이해해보기
velog는 아쉽게도 토글 기능을 지원하지 않기 때문에 안 보고 최대한 해보고 정답을 보기
async function asyncProcess() {
console.log('Process Start');
await new Promise((resolve) => {
console.log('Inner Works');
resolve('done');
}).then((data) => {
console.log('First Complete');
});
console.log('Process End');
}
console.log('Initialize');
asyncProcess().then(() => {
console.log('All Done');
});
console.log('Keep Going');
/* 실행 순서:
"Initialize"
"Process Start"
"Inner Works"
"Keep Going"
"First Complete"
"Process End"
"All Done"
*/
async function asyncFunction() {
console.log('First Step');
new Promise(resolve => {
console.log('Inner Promise');
resolve('data');
}).then(data => {
console.log('Promise Resolved');
});
Promise.resolve().then(() => {
console.log('Quick Promise');
});
console.log('Last Step');
}
console.log('Start Process');
asyncFunction().then(() => {
console.log('All Complete');
});
console.log('End Process');
/* 실행 순서:
"Start Process"
"First Step"
"Inner Promise"
"Last Step"
"End Process"
"Promise Resolved"
"Quick Promise"
"All Complete"
*/
[Javascript]비동기 처리(callback, promise, async/await)
Javascript 비동기 함수의 동작원리 (feat. EventLoop)