본문 바로가기

언어 기초/JAVASCRIPT

비동기 작업 처리 [JavaScript | 학습을 위한 자료 | 한입만 REACT]

동기와 비동기

// 동기와 비동기
// 동기 : 여러개의 작업을 순서대로 하나씩 처리하는 방식
// 멀티 쓰레드를 사용하면 오래걸리는 작업을 쓰레드별로 수행하면 되지만
// 자바스크립트에는 멀티쓰레드의 개념이 없다.
// 비동기 : 여러개의 작업을 순서대로 처리하지 않는 방식

console.log(1);

setTimeout(()=>{    // 비동기 작업들은 JS엔진이 아닌 Web APIs에서 실행됨 
    console.log(2);
}, 3000);   // 3초뒤에 수행

console.log(3);


// Web APIS
// 비동기 작업을 처리하는 영역
// setTimeout, setInterval, HTTP 요청, DOM 이벤트 핸들링 등은 Web APIs에서 처리

1. 콜백함수

// 비동기 작업 처리 1. 콜백함수
// 콜백 함수는 다른 함수에 인수로 전달되어 특정 작업이 완료된 후 실행되는 함수
// 비동기 작업 처리에서 콜백 함수는 순차적인 작업 흐름을 제어하는 데 사용

 function add(a,b, callback){
    setTimeout(() => {
        const sum = a + b; // 계산 수행
        callback(sum);     // 결과를 콜백 함수로 전달
    }, 3000); // 3초 후 실행
 }

 add(1, 2, (value) => {
    console.log(value);
 })

 // 음식을 주문하는 상황
 function orderFood(callback) {
    setTimeout(() => {
        const food = "고기";
        callback(food);     
    }, 3000);
 }

 function cooldownFood(food, callback) {
    setTimeout(() => {
        const coodownedFood = `식은 ${food}`;
        callback(coodownedFood);
    }, 2000);
 }

 function freezeFood(food, callback) {
    setTimeout(() => {
        const freezedFood = `냉동된 ${food}`;
        callback(freezedFood)
    }, 1500);
 }

 orderFood((food) => {
    console.log(food);
    cooldownFood(food, (cooldownFood) => {
        console.log(cooldownFood);

        freezeFood(cooldownFood, (freezedFood)=> {
            console.log(freezedFood);
        })
    });
 })
//문제점: 콜백 지옥(Callback Hell)
//중첩된 콜백 구조로 인해 코드가 읽기 어렵고 관리가 힘들어짐
//유지보수 및 디버깅이 복잡해짐

2. Promise

// 비동기 작업 처리 2. Promise
// 비동기 작업을 효율적으로 처리할 수 있도록 도와주는 자바스크립트의 내장 객체
// 비동기 작업을 감싸는 객체

const promise = new Promise((reslove, reject) => {
    // 비동기 작업 실행하는 함수
    // executor
		// resolve는 성공 시 호출, reject는 실패 시 호출
    setTimeout(() => {
        const num = 10;

        if (typeof num === "number" ) {
            reslove(num + 10);
        } else {
            reject("num이 숫자가 아닙니다.");
        }
        
    }, 2000);
})

// then 메서드
// 그 후에, 성공했을때만 실행
promise.then((value) => {
    console.log(value);
});

//catch 메서드
// 실패했을때 실행
promise.catch((error) => {
    console.log(error);
});

// promise 체이닝
promise
    .then((value) => {
        console.log(value);
    }).catch((error) => {
        console.log(error);
    });
    
// 콜백지옥 방지
function add10(num){
    const promise = new Promise((reslove, reject) => {
        setTimeout(() => {
            
            if (typeof num === "number" ) {
                reslove(num + 10);
            } else {
                reject("num이 숫자가 아닙니다.");
            }
            
        }, 2000);
    })

    return promise;
}

add10(0)
    .then((result) => {
        console.log(result); // 출력: 10
        return add10(result);
    })
    .then((result) => {
        console.log(result); // 출력: 20
        return add10(undefined); // 에러 발생
    })
    .then((result) => {
        console.log(result); // 실행되지 않음
    })
    .catch((error) => {
        console.log(error); // 출력: num이 숫자가 아닙니다.
    });

 


3.async

// async
// 어떤 함수를 비동기 함수로 만들어주는 키워드
// 함수가 프로미스를 반환하도록 변환해주는 키워드
// 비동기 함수는 항상 Promise 객체를 반환
// 함수 내 반환값이 Promise가 아니면 자동으로 Promise.resolve()로 감싸짐

async function getDate() {
    return {
        name : "강진호",
        id : "ggambo",
    };
}

console.log(getDate()); // 출력: Promise { <fulfilled>: { name: '강진호', id: 'ggambo' } } 

// await
// async 함수 내부에서만 사용이 가능한 키워드
// 비동기 작업이 완료될 때까지 대기하며, 해당 작업이 완료되지 않으면 함수 실행이 멈춘다

async function printData() {
    const data = await getData();
    console.log(data);
}

printData();