Programming Language/JavaScript

[JavaScript] async와 await

  • -

async 함수

async와 await이라는 문법을 사용하면 프로미스를 더 편하게 사용할 수 있습니다.

 

async 는 function 앞에 위치합니다.

async function fnc(){
    return 0;
}

 

 

함수 앞에 async를 붙이면 그 함수는 항상 프로미스를 반환합니다.

async function fnc() {
    return 'hello';
}

fnc().then(alert);

명시적으로도 프로미를 반환할 수 있습니다.

async function fnc() {
  return Promise.resolve(1);
}

fnc().then(alert);

위 두 개의 코드의 결과는 같습니다.

 

즉, async가 붙은 함수는 반드시 프로미스를 반환해 프로미스가 아닌 returun값은 프로미로 감싸 반환합니다.

await

async 함수에는 await 식이 포함될 수 있습니다. await은 함수의 실행을 일시 중지하고 전달 된 프로미의 결과를 기다린 다음 async 함수의 실행을 재시작하고 값을 반환합니다.

 

await의 문법은 다음과 같습니다.

async function fnc(){
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => resolve('success'), 1000);
    });

    let value = await promise;

    return value;
}

fnc().then(alert);

실행결과

프로미 앞에 await 키워드를 붙이면 자바스크립트는 프로미스가 처리될 때까지 대기합니다.

처리가 완료되면 아래와 같은 동작으로 이어집니다.

  • 에러 발생: 예외가 생성됨
  • 에러 미발생 - 프로미스 객체의 result 값을 반환

 

 

에러 핸들링

프로미스가 정상적으로 이행되면 await promise는 프로미스 객체의 result에 저장된 값을 반환합니다.

반면, 프로미스가 reject되면 마치 throw문을 사용한 것처럼 에러가 발생합니다.

 

await이 던진 에러는 throw가 던진 에러를 잡을 때처럼 try ... catch를 사용해 잡을 수 있습니다.

async function fnc() {
    try {
        let response = await fetch('http://유효하지-않은-주소');
        let user = await response.json();
    } catch(err) {
        console.error(err); // TypeError: failed to fetch
    }
}

fnc();

에러가 발생하면 제어 흐름이 catch 블록으로 넘어가게 됩니다.

 

try ... catch 가 없으면 아래 코드의 async 함수 fnc()를 호출해 만든 프로미스가 거부 상태가 됩니다.

이 때 fnc()에 .catch()를 추가하면 reject된 prpmise를 처리할 수 있습니다.

async function fnc() {
	let response = await fetch('http://유효하지-않은-주소');
}

fnc().catch(err => console.log(err));

 

 

 

 

async와 await을 활용한 promise chain

https://hulrud.tistory.com/33

 

[JavaScript] Promise 객체 기본 개념

프로미스 객체란? 프로미스(Promise) 객체는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 즉 비동기 함수의 실행 상태에 따라 각각의 함수를 호출하여 작업의 결과를 나타내는 것

hulrud.tistory.com


위 글에 보여드린 프로미스 체인 예제를 async와 await을 사용하여 바꾸어 보겠습니다.

const getDataPromise = num => new Promise((resolve, reject) => {
    setTimeout(() => {
        typeof num === 'number' ? resolve(num * 2) : reject('숫자가 아닙니다.');
    }, 1000);
});

getDataPromise(2)
    .then(data => getDataPromise(data))
    .then(data => getDataPromise(data))
    .then(data => console.log(data))    
    .catch(errMsg => console.log(errMsg));

위 코드는 async와 await을 사용하지 않은 프로미스 체인입니다.

 

const getDataPromise = num => new Promise((resolve, reject) => {
    setTimeout(() => {
        typeof num === 'number' ? resolve(num * 2) : reject('숫자가 아닙니다.');
    }, 1000);
});

const processData = async () => {
    try {
        let data = await getDataPromise(2);
        data = await getDataPromise(data);
        data = await getDataPromise(data);
        console.log(data);
    } catch (errMsg) {
        console.log(errMsg);
    }
};

processData();

위 코드를 실행하면 콘솔창에는 16이 출력됩니다.

 

 

 


* 위 글은 다음 문서를 참고하여 작성되었습니다.

https://ko.javascript.info/async-await

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.