await & async 함수 개념정리

태민·2022년 11월 17일
0

리액트 공부를 하면서

await를 이용한 코드를 자주 보게 되는데

자세히 알지 못해서 우선 간단하게 정리하고 이어서 공부한 부분도 정리해볼 생각이다

await 함수를 한마디로 정리하면

await : Promise 가 끝날 때 까지 기다려라

이렇게 정리 할 수 있다

await 함수는 Promise가 fulfilled 성공 또는 rejected 실패가 되든지

결과가 최종적으로 나올 때 까지는 무조건 기다리게 만드는 함수이다

await를 사용 시 제약조건이 있는데

async 함수 내부에서만 사용 할 수 있다는 것이다

비동기작업을 할 경우 마냥 기다리는 것은 비동기작업을 하는 이유와 벗어난다

한가지 일을 시켜놓고 그 일이 마무리 될 때 까지 기다리지 않고

다른 필요한 일을 할 수 있기에 비동기가 좋은 것이지만

때로는 시켜놓은 일이 완료가 되어야 다음 일이 처리가 될 수 있다

그때는 그 일이 처리가 될 때까지 기다리기위해서 우리는 함수를 사용할 수 있다

그것이 바로 await함수이다

자 그럼 이제 await 그리고 async에 대해서 조금 더 면밀히 알아보자!

Let's go!

만약에 타이머라는 함수가 있는데
그 이후에 또 타이머라는 함수가 필요하고
그 다음에 또 타이머라는 함수가 필요하다고 생각해보자

그러면 타이머 안에 또 타이머 그 안에 또 타이머

이런식으로 써주게되는데

끝에 꼬리처럼 중괄호가 계속 따라다니고
실수하기에 아주 좋은 상황이다

이런 상황을 우리는 흔히 콜백지옥이라고 부른다

이런문제를 해결하기 위해서 나온 함수가 Promise다

이렇게 적어줄 수 있는데

위에 코드와 같은 코드인데

1초가 지나면 .then하면

함수를 발동시키고 그 함수안에 포함되어있는

콘솔내용을 보여줘라 그리고 타이머1초를 리턴해라 라는 뜻이다

위 코드와 달리 이 코드는 Promise가 들어간 코드이다

콜백지옥으로 부터 벗어난 혁신적인 코드인 것 이다

함수안에 함수 그안에 함수 이런코드보다는 훨씬 좋지만

더 좋은 방법이 없을까?

왜냐면 코드 자체는 좋아졌지만 너무 지저분해졌다

자 이 코드를 보자 왼쪽이 기존에 사용하던 지저분한코드이고
오른쪽이 개선된 코드이다

await을 통해서 타이머가 1초가 되면 콘솔창을 보여줘라
또 기다렸다가 1초가 되면 보여줘라
또 기다렸다가 보여줘라

이런 코드를 짤 수 있는데

제약조건이 await을 쓰려면 async라는 것을 꼭 붙여주고 함수안에서 await을 써줘야만 한다

async가 없으면 에러가 나오고 함수밖에서 써도 에러가 나온다

이렇게 run이라는 함수를 async랑 사용해주고 그안에 await을 써준 후에

실행은 간단하게 run(); 이렇게 적어주면 잘 실행이 된다!

왼쪽에 비해 훨씬 보기 좋은 코드가 되었다!

async와 await promise 모두 활용해서

아주 간단한 예제를 만들어봤다

function timer(time){
    return new Promise(function(resolve){
        setTimeout(function(){
            resolve(time);
        },time);
    });
}

async function run(){
    console.log('start');
    let time= await timer(1000);
    console.log('time:'+time);
    time= await timer(time+1000);
    console.log('time:'+time);
    time= await timer(time+1000);
    console.log('time:'+time);
    console.log('end');
}
run();

1초뒤에 time이출력되고
2초뒤에 time
3초뒤에 time 그리고 end가 출력되도록 코드를 짰다

결과는 아래와같다

async와 await이 없었다면

대기없이 쫘르륵 나올텐데

이제는 1초 기다려
2초 기다려
3초 기다려

내가 원하는 대로 조정할 수 있게 되었다!

유레카!

async function run2(){
console.log('parent start');
await run();
console.log('parent end');
}

run2();

이렇게 작성해주면

이렇게 출력이 되는데

parent start가 제일먼저 나오고
그다음 run함수가 발동되고
그게 끝나면
parent end가 나오도록 출력한 것이다

이것역시 async await으로 사용해줬고

run2라는 함수를또 만들어서 그안에 run함수를 넣어줬다

이런식으로 응용해서도 사용이 가능하다!

한번 더 예시를 만들어봤는데

더이상 async를 사용하지 못할 경우에는 .then을 활용해서 사용하면 되는데

function timer(time){
    return new Promise(function(resolve){
        setTimeout(function(){
            resolve(time);
        },time);
    });
}

async function run(){
    console.log('start');
    let time= await timer(1000);
    console.log('time:'+time);
    time= await timer(time+1000);
    console.log('time:'+time);
    time= await timer(time+1000);
    console.log('time:'+time);
    console.log('end');
}

async function run2(){
console.log('parent start');
await run();
console.log('parent end');
}
console.log('parent parent start');
run2().then(function(){
    console.log('parent parent end');
})

이런식으로 코드를 짜개되면

이렇게 콘솔에 순서대로 내가 원하는바가 출력된다!

이렇게 await와 async를 다뤄봤는데

조금만 더 욕심을 내보자

run함수에서 return 으로 값을 time을 주게되고

run2에서 끝내기전에 console.log로 리턴값을 출력하면

이렇게 리턴값 3초라는 time:3000가 출력된다

일단 여기까지 알아보고 또 필요할 때 계속 공부해보자!

profile
몰입이 즐거운 개발자

0개의 댓글