7 React | async

Choi jeongmin·2024년 10월 1일

React

목록 보기
7/8

동기 작업과 비동기 작업

동기 작업 : 하나의 작업을 실행하고 마친 후에 작업을 순차적으로 실행

비동기 작업 : 메인 흐름은 멈추지 않은 상태에서 특정 작업들을
백그라운드에서 처리하며 동시에 처리하는 것 처럼 실행

const sayHello = () => {
    console.log("안녕");
}

setTimeout(sayHello, 3000); // 순서 2
console.log("end"); // 순서 1

setTimeout은 비동기 함수로
주어진 시간 후에 특정 코드를 실행하도록 예약하지만
기다리는 동안 나머지 코드는 계속 실행된다..
즉 비동기적으로 동작하여 코드의 흐름을 블록하지 않고 다음 작업을 이어간다.


function increase(number, callback){
    setTimeout(()=>{
        const result = number + 10;
        if(callback){ // callback = truthy
            callback(result);
        }
    }, 1000);
}

increase(0, result=>{
    console.log(result);
    increase(result, result => {
        console.log(result);
        increase(result, result=> {
            console.log(result);
        })
    })
})

여러번 순차적으로 결과물을 콜백 함수로 전달하기 위해서는
중첩을 사용해서 호출할 수 있다..
하지만 이러한 형태는 가독성도 좋지 않고, 유지보수도 힘들기 때문에
피해야 하는 패턴 중 하나이다.. 이러한 형태를 콜백 지옥이라고 한다..

그래서 비동기 함수를 왜 쓰나?

  1. 시간이 오래 걸리는 작업을 처리하기 위해서

  2. 사용자 인터페이스가 중단되지 않기 위해서..

  3. 여러 작업을 동시에 처리하기 위해서
    (실제로는 자바스크립트는 그렇게 동작하지 않지만, 이벤트 루프를 통해 동시에 처리되는 것 처럼 보임)

  4. 콜백 지옥을 해결하기 위해서

결국 느린 작업이 전체 프로그램의 흐름을 막지 않도록 하기 위함..
이러면 사용자에게 더 나은 경험을 제공할 수 있고,
특히 네트워크 요청, 파일 입출력, 타이머 같은 시간이 오래 걸리는 작업에서 큰 효과를 발휘한다..

Promise 객체

promise 는 콜백 지옥과 같은 코드가 형성되지 않게
(비동기 통신 간의 순서를 정하기 쉽게) 하는 방안으로
ES6 에서 도입되었다..

promise 객체 생성 이유?
1. 비동기 처리 함수를 실행 시 성공, 실패에 대한 처리가 용이하다..
2. promise 객체가 제공하는 메소드를 사용하기 위함
(콜백 지옥 상황을 해소해 주기 때문.. 가독성이 좋고, 메소드 체이닝 방식 제공)

const increase = number => {
    const promise = new Promise((resolve, reject)=>{ 
        setTimeout(()=>{
            const result = number + 10;
            if(result > 50){
                const e = new Error("numberToBig");
                return reject(e); // return 생략 가능
            }
            resolve(result);
        }, 1000);
    });
    return promise;
}
// Promise 객체 내부 내용을 동기로 처리한다. (기다려줌) 함수의 인자로 원하는 작업을 하고 값을 return해준다. - 성공 : resolve(값), 실패: reject(값)

console.log(increase(0)); // Promise { <pending> } // 값을 반환하는게 아니라 비동기로 처리한 약속자체를 반환해준다.

// 체이닝
// promise 객체는 then 메소드를 사용하여 비동기 작업의 결과를 처리할 수 있다..

increase(0).then(number => {
    console.log(number)
    return increase(number);
}).then(number => {
    console.log(number);
    return increase(number);
}).catch(e=>console.log(e, "가 발생했네")); // then() 인자로 결과값을 받아옴..
  1. resolve 값 반환
    -> increase() 의 인자값 40이하 넣었을 때 값 출력

  2. reject 값 반환
    -> increase() 의 인자값 41이상 일때 에러발생 catch에 넣어둔 값 발생
    Error: numberToBig
    at Timeout._onTimeout (c:\20240801-gangnam\07_react\04_async\src\01_intro\03_promise.js:17:27)
    at listOnTimeout (node:internal/timers:581:17)
    at process.processTimers (node:internal/timers:519:7) 가 발생했네

async / await

  • Promise : 비동기 작업의 결과를 처리하는 객체
  • async/await : 비동기 작업을 동기적으로 실행하는 것 처럼 보이게 만드는 구문
    then() 과 await : promise 의 결과를 사용할 때
    then() 을 사용하거나, async 함수 내에서 await 로 처리할 수 있음..
function increase (number){
    const promise = new Promise((resolve, reject)=>{
        setTimeout(()=>{
            const result = number + 10;
            if(result > 50){
                const e = new Error("number to big");
                return reject(e);
            }
            resolve(result);
        }, 1000);
    });
    return promise;
}


// async : 비동기 함수를 정의
async function run(){
    try{
        // resolve 값 받음
        let result = await increase(1); // await : 결과값을 기다렸다가 반환
        console.log(result);

        result = await increase(2);
        console.log(result);

        result = await increase(3);
        console.log(result);

        result = await increase(4);
        console.log(result);

        result = await increase(5);
        console.log(result);

        result = await increase(6);
        console.log(result);
        
        return result;
    }catch(e){
        // reject 값 받음
        console.log(e, "가 발생함");
    }
}

const value = async () => {
    const runValue = await run();
    console.log("value " + runValue);
}

const result = value();
/* console.log(result); // Promise { <pending> } */

0개의 댓글