비동기처리(콜백함수, Promise, async/await)

Yoon·2021년 7월 14일
0

Javascript

목록 보기
2/8
post-thumbnail
  • JS는 싱글스레드이다.
    싱글스레드란 간단히 말하면, 한번에 하나의 일을 처리하는 것을 의미한다.
    이러한 특징때문에 어떤 일을 수행하는데 시간이 오래걸리면, 다른 작업들은 그만큼 기다려야 한다는 단점이있다. => Blocking

💡 비동기 처리

이를 해결하기 위해, '비동기 처리'가 등장하게 된다!
비동기(Asynchronous)는 어떤 일을 수행할 때, 순차적으로 진행하는 것이 아닌 병렬적으로 처리한다.
Blocking을 방지해준다.

  • 브라우저에서의 비동기 프로그래밍은 주로 통신과 같이 오래 걸리는 작업들을 브라우저에 위임할 때 이루어진다.
  • 서버와의 통신을 할때 받아오는 데이터의 크기가 크고 많을 때 동기적처리를 하면 데이터를 모두 받아오는 시간을 기다린 후에 다음코드를 처리할 것이지만 비동기처리를 이용하면 기다리지 않고 코드 처리가 가능하다.

즉, 비동기는 요청을 보낸 후 응답과 관계없이 다음 동작을 실행할 수 있는 방식을 의미한다.

✅ 콜백 함수 사용

  • 콜백함수는 특정 함수에 매개변수로 전달된 함수를 의미한다.
    그 콜백함수는 함수를 전달받은 함수 안에서 호출된다.

  • setTimeout함수

  • 콜백 지옥 예시
    계속 콜백을 호출한다.
const f1 = (callback)=>{
    setTimeout(function(){
        console.log("1번 주문 완료");
        callback();
    },1000);
};
const f2 = (callback)=>{
    setTimeout(function(){
        console.log('2번 주문 완료');
        callback();
    },2000);
};
const f3 = (callback)=>{
    setTimeout(function(){
        console.log('3번 주문 완료');
        callback();
    },3000);
};
console.log('시작');
f1(function(){
    f2(function(){
        f3(function(){
            console.log("끝");
        });
    });
});

콜백 사용의 단점
1. 가독성이 떨어진다.
2. 에러처리를 한다면 모든 콜백에서 각각 에러 핸들링을 해주어야 한다.

✅ Promise

  • promise는 작업이 완료되거나 실행되었을 때 알려준다.

  • resolve(성공), reject(실패)

  • new Promise객체가 반환하는 프로미스 개체는 state와 result
    처음에는 > state : pending(대기), result : undefined
    resolve(value)호출되면(성공시) > state : fulfilled , result:value
    reject(error)호출되면(실패시) > satate : rejected , result:error

const pr = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('OK')
    },3000)
});
//3초 후에 state:fufilled, result:'OK'

pr.then(
    function(result){
        console.log(reulst + ' 가지러 가자.');
    },//이행되었을때 실행 result:'OK'
    function(err){
        console.log('다시 주문해주세요..');
    }//거부되었을 때 실행
);

//then 이외에 catch사용 가능 단, catch는 에러에만 사용할 수 있다.
//finally는 이행이든 거부든 완료되면 실행됨
pr.then((result)=>{
    console.log(result);
})
.catch((err)=>{
    console.log(err);
})
.finally(()=>{
    console.log('---주문 끝---')
})
  • 콜백함수 사용하지 않고 Promise로 구현!
const f1 = () => {
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res('1번 주문 완료');
        },1000);
    })
}
const f2 = (message) =>{
    console.log(message);
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res('2번 주문 완료');
        },3000);
    })
}
const f3 = (message) =>{
    console.log(message);
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res('3번 주문 완료');
        },2000);
    })
}
//프로미스가 연결연결되는것을
//프로미스 체이닝(Promise chaning)이라고 함
console.log('시작');
f1()
.then((res)=>f2(res))
.then((res)=>f3(res))
.then((res)=>console.log(res))
.catch(console.log)
.finally(()=>{
    console.log('끝');
});

Promise 추가적인 기능

  • promise.all
//Promise.all //배열사용
//한번에처리 //시간 절약 가능
//하지만 하나라도 누락되면 아예안보여줌.
//다 보여주거나 다 안보여줄때 사용함
Promise.all([f1(),f2(),f3()])
.then(res =>{
    console.log(res);
})
  • promise.race
//Promise.race //하나라도 완료되면 끝내버림
Promise.race([f1(),f2(),f3()])
.then(res =>{
    console.log(res);
})

✅ async/await

  • Promise로 결과를 반환한다.

  • async/await를 사용하면 비동기 코드를 마치 동기 코드처럼 보이게 작성할 수 있다.

  • Promise에 then메소드를 체인형식(프로미스체이닝)으로 호출하는것보다 가속성이 좋다. Promise를 사용하지만 then, catch 메소드를 사용하여 컨트롤 하는 것이 아닌 동기적 코드처럼 반환 값을 변수에 할당하여 작성할 수 있게끔 도와주는 것!

  • await는 async 내부 함수에서만 사용 가능하다.
    Promise를 리턴하는 모든 비동기 함수 호출부 앞에 await를 붙인다.
    await를 사용하면 결과값을 얻을 수 있을 때까지 기다려주어 동기적 코드 처리와 동일한 흐름으로 코드를 작성할 수 있다. //함수 호출 후 결과값을 변수에 할당하는 것처럼 작성할 수 있다는 것이다.

  • 동기식 코드에서 쓰는 try...catch 구문을 async/await구조에서 사용할 수 있다.

function getName(name){
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res(name);
        },1000)
    })
}
async function showName(){
    const res = await getName("Mike");
    console.log(res);
}
console.log('시작');
showName();
/*
출력값:

시작
Mike
*/

async~await로 구현

const f1 = () => {
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res('1번 주문 완료');
        },1000);
    })
}
const f2 = (message) =>{
    console.log(message);
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            // res('2번 주문 완료');
            rej(new Error("err.."));
        },3000);
    })
}
const f3 = (message) =>{
    console.log(message);
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            res('3번 주문 완료');
        },2000);
    })
}
console.log("시작");
//reject 에러발생시 try~catch문 이용
async function order(){
    try{
        const result1 = await f1();
        const result2 = await f2(result1);
        const result3 = await f3(result2);
        console.log(result3);
    }catch(e){
        //에러처리
        console.log(e);
    }
    console.log('종료');
}
order();

참고자료 : https://www.daleseo.com/js-async-async-await/

profile
FE Developer✨

0개의 댓글